Skip to content

Instantly share code, notes, and snippets.

@kdridi
Created May 20, 2018 17:44
Show Gist options
  • Save kdridi/eeab9c28378b52a646fe11a65a46b7ea to your computer and use it in GitHub Desktop.
Save kdridi/eeab9c28378b52a646fe11a65a46b7ea to your computer and use it in GitHub Desktop.
package matchstick;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import competitive.programming.gametheory.ICancellableMove;
import competitive.programming.gametheory.IGame;
import competitive.programming.gametheory.IMoveGenerator;
import competitive.programming.gametheory.minimax.Minimax;
import competitive.programming.timemanagement.Timer;
import matchstick.Application.Game.Generator;
import matchstick.Application.Game.Move;
public class Application {
public static class Game implements IGame {
private final int[] values;
private final int max;
private final int players;
private final int player;
private Game(int[] values, int max, int players, int player) {
super();
this.values = values;
this.max = max;
this.players = players;
this.player = player;
}
public void writeTo(PrintWriter s) {
final int size = 3 + 2 * values.length;
s.print(repeatChar(' ', 4));
s.println(repeatChar('*', size));
for (int i = 0; i < values.length; i++) {
final int length = values[i];
final int half = (size - (length + 1)) / 2;
s.print(String.format("[%02d]", i + 1));
s.print(repeatChar('*', 1));
s.print(repeatChar(' ', half));
s.print(repeatChar('|', length));
s.print(repeatChar(' ', size - half - length - 2));
s.print(repeatChar('*', 1));
s.println(String.format("[%02d]", length));
}
s.print(repeatChar(' ', 4));
s.println(repeatChar('*', size));
}
private String repeatChar(char c, int n) {
final StringBuffer buffer = new StringBuffer();
while (n > 0) {
buffer.append(c);
n -= 1;
}
return buffer.toString();
}
@Override
public String toString() {
final StringWriter w = new StringWriter();
final PrintWriter writer = new PrintWriter(w);
writeTo(writer);
writer.close();
return w.toString();
}
public static Game createGame(int height, int max, int players) {
int values[] = new int[height];
for (int i = 0; i < values.length; i++)
values[i] = 2 * i + 1;
return new Game(values, max, players, 0);
}
public static class Move implements ICancellableMove<Game> {
private final int line;
private final int count;
public Move(int line, int count) {
super();
this.line = line;
this.count = count;
}
@Override
public Game execute(Game game) {
return next(game, 0 + 1);
}
private Game next(Game game, int direction) {
int values[] = new int[game.values.length];
for (int i = 0; i < values.length; i++) {
values[i] = game.values[i];
if (i == line)
values[i] -= count * direction;
if (values[i] < 0)
throw new RuntimeException("ERROR TOO LESS");
if (values[i] > 2 * i + 1)
throw new RuntimeException("ERROR TOO MUCH");
}
int max = game.max;
int players = game.players;
int player = (players + game.player + direction) % players;
return new Game(values, max, players, player);
}
@Override
public Game cancel(Game game) {
return next(game, 0 - 1);
}
}
public static class Generator implements IMoveGenerator<Move, Game> {
@Override
public List<Move> generateMoves(Game game) {
final List<Move> result = new ArrayList<>();
for (int line = 0; line < game.values.length; line++)
for (int count = 1; count <= game.max && count <= game.values[line]; count++)
result.add(new Move(line, count));
return result;
}
}
@Override
public int currentPlayer() {
return player;
}
@Override
public double[] evaluate(int depth) {
int count = 0;
for (int i = 0; i < values.length; i++)
count += values[i];
double[] result = new double[players];
for (int i = 0; i < result.length; i++)
result[i] = (count != 1) ? 0 : (i == player ? 0 - 1 : 0 + 1);
return result;
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Timer timer = new Timer();
Game.Generator generator = new Generator();
Game game = Game.createGame(5, 3, 2);
while (generator.generateMoves(game).isEmpty() == false) {
System.out.println(game.toString());
Game.Move move = nextMove(in, timer, generator, game, game.currentPlayer() != 0);
game = move.execute(game);
}
}
private static Move nextMove(Scanner in, Timer timer, Generator generator, Game game, boolean ai) {
if (ai) {
timer.startTimer(1000 * 3600);
final Minimax<Move, Game> minimax = new Minimax<Game.Move, Game>(timer);
return minimax.best(game, generator, 0, 100);
}
Game.Move result = null;
final List<Move> moves = generator.generateMoves(game);
while (result == null) {
System.out.println("CHOOSE LINE: ");
final int line = in.nextInt() - 1;
System.out.println("CHOOSE COUNT: ");
final int count = in.nextInt();
for (Game.Move move : moves) {
if (move.line == line && move.count == count) {
result = move;
break;
}
}
}
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment