У меня консольная программа крестики-нолики. Для тестирования ввода с консоли я использую класс StubInput
:
public class StubInput implements In {
/**
* Contain answers required string type.
*/
private String[] answersStr;
/**
* Counter for get next value from answersStr.
*/
private int countStr = 0;
/**
* Contain answers required int type.
*/
private int[] answersNum;
/**
* Counter for get next value from answersNum.
*/
private int countNum = 0;
public void setAnswersStr(String[] answersStr) {
this.answersStr = answersStr;
}
public void setAnswersNum(int[] answersNum) {
this.answersNum = answersNum;
}
/**
* Emulator string input stream.
* @return string answer.
*/
@Override
public String getStrInput() {
return this.answersStr[this.countStr++];
}
/**
* Emulator int input stream.
* @return int answer.
*/
@Override
public int getNumInput() {
return this.answersNum[this.countNum++];
}
}
И для класса отвечающего за доску в котором есть возможность выбора размера доски это сработало:
public class Desc implements Board {
/**
* Information about statement desc for bot.
*/
private static char[][] infoDesc;
/**
* Input for get console in.
*/
private In input = new Input();
/**
* Desc for game.
*/
private char[][] desc = new char[3][3];
/**
* Pointer on desc. It's information for bot about statement desc.
*
* @return current statement desc.
*/
public static char[][] getInfoDesc() {
return infoDesc;
}
/**
* Use for test class StubInput.
*
* @param input emulation console input stream.
*/
@Override
public void setInput(In input) {
this.input = input;
}
/**
* Getter for desc. Init infoDesc.
*
* @return desc.
*/
@Override
public char[][] getDesc() {
infoDesc = this.desc;
return this.desc;
}
/**
* For choice desc size.
*/
@Override
public void initDescSize() {
System.out.println("Хотите использовать стандартный размер поля: y/n");
String answer = this.input.getStrInput();
if (answer.equals("y")) {
System.out.println("Установлен стандартный размер поля: 3/3");
} else if (answer.equals("n")) {
this.initNonstandardDesc();
}
this.initContentDesc();
}
/**
* Install desc nonstandard size.
*/
private void initNonstandardDesc() {
System.out.println("Введите размер сторон:");
int i = this.input.getNumInput();
this.desc = new char[i][i];
System.out.println(format("Установлен размер поля: %s/%s", i, i));
}
/**
* Fill desc empty call. Empty is ' '.
*/
private void initContentDesc() {
for (int i = 0; i != this.desc.length; i++) {
for (int j = 0; j != this.desc.length; j++) {
this.desc[j][i] = ' ';
}
}
}
}
Вот тест к нему:
public class DescTest {
/**
* Test choice standard desc size.
* @see Desc#initDescSize()
*/
@Test
public void whenUserChoiceStandardDescSizeThenDeskSizeEqualTreeToTree() {
StubInput input = new StubInput();
Board desc = new Desc();
input.setAnswersStr(new String[]{"y"});
desc.setInput(input);
desc.initDescSize();
int result = desc.getDesc().length;
assertThat(result, is(3));
}
/**
* Test case when user choice nonstandard desc size.
*/
@Test
public void whenUserChoiceNonstandardThenSizeThenDeskSizeEqualUserInput() {
StubInput input = new StubInput();
Board desc = new Desc();
input.setAnswersStr(new String[]{"n"});
input.setAnswersNum(new int[]{5});
desc.setInput(input);
desc.initDescSize();
int result = desc.getDesc().length;
assertThat(result, is(5));
}
}
Однако когда я попробовал протестировать класс самой игры у меня ничего не вышло. Вот сама игра:
public class Game implements Round {
/**
* Desc for play.
*/
private Board desc = new Desc();
/**
* winner.
*/
private Gamers winner;
/**
* For input.
*/
private In input = new Input();
/**
* List contain all gamer: bot and user.
*/
private ArrayList<Gamers> gamers = new ArrayList<>();
/**
* Util class contain algorithm determining winner.
*/
private Validation valid = new ValidationWinnerUtil();
@Override
public Gamers getWinner() {
return this.winner;
}
/**
* Check correct move.
* @param player player which move.
* @return true if move success. False if move fail
*/
private boolean move(Gamers player) {
player.setPosit();
if (this.desc.getDesc()[player.getPosit().getY()][player.getPosit().getX()] == ' ') {
this.desc.getDesc()[player.getPosit().getY()][player.getPosit().getX()] = player.getColor();
return true;
} else {
System.err.println("Так ходить нельзя!");
return false;
}
}
/**
* Determines fist move.
*/
@Override
public void firstMove() {
this.desc.initDescSize();
System.out.println("Кто ходит первым? Enter: Bot / I");
if (this.input.getStrInput().toUpperCase().equals("BOT")) {
this.fstMoveBot();
} else {
this.fstMoveUsr();
}
Printer.printDesc(this.desc.getDesc());
this.loopMoves();
}
/**
* Configurable statement game if bot move first.
*/
private void fstMoveBot() {
this.gamers.add(new Bot(Colors.X.getColor()));
this.gamers.add(new User(Colors.O.getColor()));
}
/**
* Configurable statement game if user choice move first.
*/
private void fstMoveUsr() {
this.gamers.add(new User(Colors.X.getColor()));
this.gamers.add(new Bot(Colors.O.getColor()));
}
/**
* Loop game process.
*/
private void loopMoves() {
Gamers winner = null;
while (this.valid.gameCanGoOn(this.desc.getDesc())) {
for (Gamers gamer : this.gamers) {
if (this.valid.gameCanGoOn(this.desc.getDesc()) &&
this.move(gamer)
) {
Printer.printDesc(this.desc.getDesc());
winner = gamer;
} else if (this.valid.gameCanGoOn(this.desc.getDesc())) {
this.mistakeMove(gamer);
Printer.printDesc(this.desc.getDesc());
}
}
}
this.initResultGame(winner);
}
/**
* Give more chance when player which mistake - try move in busy cell.
* @param gamer player which mistake.
*/
private void mistakeMove(Gamers gamer) {
while (!this.move(gamer)) {
mistakeMove(gamer);
}
}
/**
* Init result game.
* @see TickTack#winners
* @param winner gamer for estimated award.
*/
private void initResultGame(Gamers winner) {
if (!this.valid.emptyCellExist( this.desc.getDesc()) &&
!this.valid.winnerDetermines(this.desc.getDesc())
) {
System.out.println("Ничья.");
} else if (this.valid.winnerDetermines( this.desc.getDesc())) {
this.winner = winner;
System.out.println(format("Победитель: %s", winner.getColor()));
}
}
}
Проблема заключается в том что когда метод firstMove()
начинает работу то поток выполнения передается до самого конца партии, и у меня нет возможности для того чтобы подменить Input
на StubInput
в объекте пользователя вот тут:
private void fstMoveBot() {
this.gamers.add(new Bot(Colors.X.getColor()));
this.gamers.add(new User(Colors.O.getColor())); // вот тут new User
}
Но и перед запуском firstMove()
я тоже этой подмены сделать не могу так как firstMove()
все равно их перепишет.
В общем такая проблема... С заранее не записать так как все равно перепишется, а в процессе вклинится не как. И даже если я и создам указатель на:
this.gamers.add(какой-то_указатель_с_полей = new User(Colors.O.getColor()))
это так же ничего не даст.
Помогите пожалуйста. Что мне делать? Как мне протестировать это? Может сам код г-но, потому и не тестируется тогда подскажите в чем. В общем вот. Буду безумно благодарен за помощь и любую конструктивную критику...
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Есть задание сделать анаграмму ,например lashjkuj2 akcc66Чтобы все не буквенные символы остались на месте? Я сделал так
Подскажите, пожалуйста, способ нахождения самой длинной строки в ArrayList
Запустил приложение все работало ,обнавил страницу выдал ошибку перезапустил снов одно и тожеЧто это с чем связано ребята??помогите при...