abstract class XOInterface {
private int currentPlayer;
private int[] fields;
public XOInterface() {
this.currentPlayer = 0;
this.fields = new int[]{ 0,0,0,0,0,0,0,0,0 };
}
public int getPlayer() {
return currentPlayer;
}
public void setPlayer(int newPlayer) {
currentPlayer = newPlayer;
}
public int[] getFields() {
return fields;
}
protected boolean setField(int field, int value) {
fields[field] = value;
int x = field % 3;
int y = field / 3;
boolean diag1 = x == y;
boolean diag2 = x + y == 2;
int[] count = new int[] {0,0,0,0};
boolean win = false;
for(int i = 0; i < 3; i++) {
if(fields[i*3+x] == value)
count[0] += 1;
if(fields[y*3+i] == value)
count[1] += 1;
if(diag1)
if(fields[4*i] == value)
count[2] += 1;
if(diag2)
if(fields[2+2*i] == value)
count[3] += 1;
}
for(int i = 0; i < 4; i++)
if(count[i] == 3)
win = true;
return win;
}
public void resetFields() {
this.fields = new int[]{ 0,0,0,0,0,0,0,0,0 };
}
public abstract void start();
public abstract boolean play(int field);
public abstract void stop();
}
public class Main {
public static void main(String[] args) throws Exception{
try (Scanner scanner = new Scanner(System.in)) {
String line = scanner.nextLine();
EdgarTestRunner.run(line);
}
}
public static class MainTest {
@Test
@Tag("constructor")
@DisplayName("Check XO constructor")
void checkConstructor() {
int[] array = new int[]{ 0,0,0,0,0,0,0,0,0 };
XO xo = new XO();
assertThat(xo.getPlayer(), is(0));
assertThat(xo.getFields(), is(array));
}
@Test
@Tag("exceptions")
@DisplayName("Check exceptions")
void checkException() {
XO xo = new XO();
try{
xo.stop();
} catch(XOException e) {
assertThat(e.getMessage(), is("Game already stopped"));
}
try{
xo.play(2);
} catch(XOException e) {
assertThat(e.getMessage(), is("Game not started"));
}
xo.start();
try{
xo.start();
} catch(XOException e) {
assertThat(e.getMessage(), is("Game already started"));
}
try{
xo.play(-1);
} catch(XOException e) {
assertThat(e.getMessage(), is("Invalid field"));
}
try{
xo.play(9);
} catch(XOException e) {
assertThat(e.getMessage(), is("Invalid field"));
}
xo.play(3);
try {
xo.play(3);
} catch(XOException e) {
assertThat(e.getMessage(), is("Field already taken"));
}
}
@ParameterizedTest
@Tag("win")
@DisplayName("Check win conditions")
@CsvSource({"0,4,8,1,2,5", "2,4,6,0,1,3", "0,1,2,3,6,7", "1,4,7,0,2,3"})
void checkWin(int win1, int win2, int win3, int lose1, int lose2, int lose3) {
int[] win = new int[]{win1,win2,win3};
int[] lose = new int[]{lose1,lose2,lose3};
XO xo1 = new XO();
xo1.start();
XO xo2 = new XO();
xo2.start();
boolean winFlag1 = false;
boolean winFlag2 = false;
for(int i = 0; i < 3; i++){
winFlag1 = xo1.play(win[i]);
if(i < 2)
xo1.play(lose[i]);
xo2.play(lose[i]);
winFlag2 = xo2.play(win[i]);
}
assertThat(winFlag1, is(false));
assertThat(winFlag2, is(true));
assertThat(xo1.getPlayer(), is(0));
assertThat(xo2.getPlayer(), is(0));
}
@ParameterizedTest
@Tag("draw")
@DisplayName("Check draw condition")
@CsvSource({"0,2,5,6,7,1,3,4,8", "1,2,3,4,8,0,5,6,7"})
void checkDraw(int x1, int x2, int x3, int x4, int x5, int o1, int o2, int o3, int o4) {
int[] first = new int[]{x1, x2, x3, x4, x5};
int[] second = new int[]{o1, o2, o3, o4};
XO xo = new XO();
xo.start();
boolean win = false;
for(int i = 0; i < 5; i++){
win = xo.play(first[i]);
if(i < 4){
xo.play(second[i]);
}
}
assertThat(win, is(false));
assertThat(xo.getPlayer(), is(0));
}
}
}