mirror of
https://github.com/Xevion/contest.git
synced 2025-12-10 02:06:48 -06:00
A+ January 2017: Othello
Actually a sorta interesting problem. I really like doing this one, and it was super nice to do, seeing how my only errors came up in understanding the problem whether it was considering diagonals or not - it was! And the fix for that was super easy since I programmed it to have very expandable behavior.
This commit is contained in:
211
uil/aplus-january-2017/src/Othello.java
Normal file
211
uil/aplus-january-2017/src/Othello.java
Normal file
@@ -0,0 +1,211 @@
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Scanner;
|
||||
|
||||
class Point
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
|
||||
Point(int x, int y)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
Point()
|
||||
{
|
||||
this(0, 0);
|
||||
}
|
||||
|
||||
public Point add(Point other)
|
||||
{
|
||||
return new Point(this.x + other.x, this.y + other.y);
|
||||
}
|
||||
|
||||
public Point subtract(Point other)
|
||||
{
|
||||
return new Point(this.x - other.x, this.y - other.y);
|
||||
}
|
||||
|
||||
public Point multiply(int magnitude)
|
||||
{
|
||||
return new Point(this.x * magnitude, this.y * magnitude);
|
||||
}
|
||||
|
||||
public Point multiply(Point other)
|
||||
{
|
||||
return new Point(this.x * other.x, this.y * other.y);
|
||||
}
|
||||
}
|
||||
|
||||
class OthelloBoard
|
||||
{
|
||||
private final int[][] tiles = new int[8][8];
|
||||
|
||||
public static final Point[] directions = new Point[]{
|
||||
new Point(0, 1), // Down
|
||||
new Point(1, 0), // Right
|
||||
new Point(-1, 0), // Left
|
||||
new Point(0, -1), // Up
|
||||
new Point(1, 1), // Down + Right
|
||||
new Point(-1, 1), // Down + Left
|
||||
new Point(-1, -1), // Up + Left
|
||||
new Point(1, -1), // Up + Right
|
||||
};
|
||||
|
||||
public static final int BLACK = -1;
|
||||
public static final int EMPTY = 0;
|
||||
public static final int WHITE = 1;
|
||||
|
||||
OthelloBoard()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param data Input row data
|
||||
* @param row The row number to modify.
|
||||
*/
|
||||
public void read(char[] data, int row)
|
||||
{
|
||||
for (int x = 0; x < 8; x++) {
|
||||
char next = data[x];
|
||||
tiles[row][x] = next == 'B' ? BLACK : (next == 'W' ? WHITE : EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Places a tile and evaluates the result.
|
||||
*
|
||||
* @param x Column of placement
|
||||
* @param y Row of placement
|
||||
* @param white Whether or not the tile being placed is white.
|
||||
* @return Returns true if any tiles were flipped in the placement of the new tile.
|
||||
*/
|
||||
public boolean place(int x, int y, boolean white)
|
||||
{
|
||||
final int SELF = white ? WHITE : BLACK; // The tile type we are placing.
|
||||
final int OTHER = white ? BLACK : WHITE; // The tile type we will be trying to flip.
|
||||
final Point start = new Point(x, y); // The point we start at.
|
||||
ArrayList<Point> flipped = new ArrayList<Point>(); // Tiles that will be flipped after move is completed.
|
||||
|
||||
// Start moving as far as possible in each direction
|
||||
for (Point direction : directions) {
|
||||
ArrayList<Point> between = new ArrayList<Point>(); // The tiles we found in between the end point (if any)
|
||||
Point current = start.add(direction);
|
||||
|
||||
// Move forward in each direction as long as the tile is the opposite tile type
|
||||
while (getTile(current) == OTHER) {
|
||||
between.add(current); // Another tile between the two end points
|
||||
current = current.add(direction); // Move forward another in that direction
|
||||
|
||||
// If the current position is no longer valid, break
|
||||
if (!isValid(current))
|
||||
break;
|
||||
}
|
||||
|
||||
// If the end positio n is valid and it's the same as our placing tile, we've found a valid area
|
||||
if (isValid(current) && getTile(current) == SELF) {
|
||||
flipped.addAll(between);
|
||||
}
|
||||
}
|
||||
|
||||
// Set tile down
|
||||
tiles[y][x] = white ? WHITE : BLACK;
|
||||
|
||||
// Flip all tiles found
|
||||
for (Point unflippedPoint : flipped)
|
||||
flip(unflippedPoint);
|
||||
|
||||
return flipped.size() > 0;
|
||||
}
|
||||
|
||||
private void flip(Point tile)
|
||||
{
|
||||
flip(tile.x, tile.y);
|
||||
}
|
||||
|
||||
private void flip(int x, int y)
|
||||
{
|
||||
int current = tiles[y][x];
|
||||
if (current == WHITE)
|
||||
tiles[y][x] = BLACK;
|
||||
else if (current == BLACK)
|
||||
tiles[y][x] = WHITE;
|
||||
}
|
||||
|
||||
private boolean isValid(Point point)
|
||||
{
|
||||
return isValid(point.x, point.y);
|
||||
}
|
||||
|
||||
private boolean isValid(int x, int y)
|
||||
{
|
||||
return x >= 0 && y >= 0 && y < tiles.length && x < tiles[0].length;
|
||||
}
|
||||
|
||||
|
||||
public int getTile(Point point)
|
||||
{
|
||||
return getTile(point.x, point.y);
|
||||
}
|
||||
|
||||
public int getTile(int x, int y)
|
||||
{
|
||||
return tiles[y][x];
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int y = 0; y < tiles.length; y++) {
|
||||
for (int x = 0; x < tiles[y].length; x++) {
|
||||
switch (tiles[y][x]) {
|
||||
case 0:
|
||||
sb.append(".");
|
||||
break;
|
||||
case -1:
|
||||
sb.append("B");
|
||||
break;
|
||||
case 1:
|
||||
sb.append("W");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (y < tiles.length - 1)
|
||||
sb.append("\n");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public class Othello
|
||||
{
|
||||
public static void main(String[] args) throws FileNotFoundException
|
||||
{
|
||||
Scanner in = new Scanner(new File("othello.dat"));
|
||||
int inputs = in.nextInt();
|
||||
in.nextLine();
|
||||
|
||||
for (int i = 0; i < inputs; i++) {
|
||||
OthelloBoard board = new OthelloBoard();
|
||||
for (int y = 0; y < 8; y++) {
|
||||
board.read(in.nextLine().toCharArray(), y);
|
||||
}
|
||||
|
||||
int row = in.nextInt();
|
||||
int column = in.nextInt();
|
||||
char move = in.next("[BW]").charAt(0);
|
||||
in.nextLine();
|
||||
|
||||
boolean change = board.place(column, row, move == 'W');
|
||||
System.out.println(change ? board : "Invalid Move");
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user