Skip to content

Instantly share code, notes, and snippets.

@dizzi
Created December 7, 2010 20:28
Show Gist options
  • Save dizzi/732350 to your computer and use it in GitHub Desktop.
Save dizzi/732350 to your computer and use it in GitHub Desktop.
package pal;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
public class Main {
static boolean local = true;
static int wKing, kKing, wRook, kRook, wPawn;
static int horizont = 0;
static int edgeSize = 7;
static int initStatus = 0;
static int left = 1;
static int right = 2;
static int none = 0;
static int white = 1;
static int black = 2;
static int king = 1;
static int rook = 2;
static int pawn = 3;
static int queen = 4;
static int boardSize = edgeSize * edgeSize;
/** True = white, False = black */
static boolean starts = true;
public static void main(String[] args) throws Exception {
if (args.length != 0) {
local = true;
} else {
local = false;
}
Main task = new Main();
task.initData();
int[] moves = task.generateMoves(Main.initStatus, Main.white);
for(int move : moves){
if(move == 0)break;
// System.out.println(Utils.getPieceMoveKind(move)+" "+Utils.getPieceMoveFrom(move)+" "+Utils.getPieceMoveTo(move));
}
//TestCases.testRookMap(task);
}
int moveToStatus(int color, int piece, int newPosition, int status){
if(Main.white==color){
if(Main.king==piece){
return Utils.setWhiteKing(status, newPosition);
}else if(Main.rook==piece){
return Utils.setWhiteRook(status, newPosition);
}else{
return Utils.setWhitePawn(status, newPosition);
}
}else{
if(Main.king==piece){
return Utils.setBlackKing(status, newPosition);
}else if(Main.rook==piece){
return Utils.setBlackRook(status, newPosition);
}
}
return status;
}
int maxi(int depth, int status, boolean firstLevel) {
int[] moves = generateMoves(status, Main.white);
if (depth == 0)
return evaluate(moves.length);
int max = Integer.MIN_VALUE;
int score = 0;
for (int move : moves) {
score = mini(depth - 1, moveToStatus(Main.white, Utils.getPieceMoveKind(move), Utils.getPieceMoveTo(move), status));
if (score > max)
max = score;
if(firstLevel && score==Integer.MAX_VALUE){
System.out.println(String.format("%s -> %s", Utils.getPieceMoveKind(move), Utils.getPieceMoveTo(move)));
}
}
if(firstLevel && score!=Integer.MAX_VALUE)
System.out.print("Nevyhraje");
return max;
}
int mini(int depth, int status) {
int[] moves = generateMoves(status, Main.black);
if (depth == 0) //? mozna <0
return -evaluate(moves.length);
int min = Integer.MAX_VALUE;
int score = 0;
for (int move : moves) {
score = maxi(depth - 1, moveToStatus(Main.black, Utils.getPieceMoveKind(move), Utils.getPieceMoveTo(move), status), false);
if (score < min)
min = score;
}
return min;
}
private int[] generateMoves(int status, int color) {
int[] moves = new int[45];
long whites = 0, blacks = 0;
blacks |= Utils.setBit(Utils.getBlackKing(status), 0);
blacks |= Utils.setBit(Utils.getBlackRook(status), 0);
whites |= Utils.setBit(Utils.getWhiteKing(status), 0);
whites |= Utils.setBit(Utils.getWhiteRook(status), 0);
whites |= Utils.setBit(Utils.getWhitePawn(status), 0);
long whiteAttack = 0;
long blackAttack = 0;
long pawnAttack = 0;
long whiteKingAttack = 0;
long whiteRookAttack = 0;
long blackKingAttack = 0;
long blackRookAttack = 0;
long whiteRookAttackReverify = 0;
long blackRookAttackReverify = 0;
long tmp = 0;
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////black pieces////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
// init raw attacks - without chess checking
blackKingAttack |= MapGenerator.generateKingMap(Utils.getBlackKing(status));
// rook - moves + shadow attacks + chess check
blackRookAttack |= MapGenerator.generateRookMap(Utils.getBlackRook(status));
blackRookAttack = ~(blacks) & blackRookAttack;
blackRookAttack = validateRookMoves(Utils.getBlackRook(status), blackRookAttack);
long temp = blackRookAttack & whites; // remember placement of reachable whites
blackRookAttack = ~(whites) & blackRookAttack;
blackRookAttack = validateRookMoves(Utils.getBlackRook(status), blackRookAttack);
// now add whites only - we can attack them
blackRookAttack |= temp;
// remove attacks on king's new moves y/n (n-ok, y-analyse)
if ((whiteAttack & blackKingAttack) != 0) { // TODO white attack can be eliminated
blackKingAttack = blackKingAttack & ~whiteRookAttack;
blackKingAttack = blackKingAttack & ~whiteKingAttack;
blackKingAttack = blackKingAttack & ~pawnAttack;
}
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////white pieces////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
// blackAttack |=
// MapGenerator.generateKingMap(Utils.getBlackKing(status));
// blackAttack |=
// MapGenerator.generateRookMap(Utils.getBlackRook(status));
// generate white king, rook and pawn attack maps
// king - moves + chess check
whiteKingAttack |= MapGenerator.generateKingMap(Utils.getWhiteKing(status));
// pawn - moves + attacks + chess check
pawnAttack |= MapGenerator.generatePawnQueenMap(Utils.getWhitePawn(status), true);
tmp |= MapGenerator.generatePawnAttackMap(Utils.getWhitePawn(status));
// if pawn can attack someone add this moves to the white moves
pawnAttack |= (tmp & blacks);
// rook - moves + shadow attacks + chess check
whiteRookAttack |= MapGenerator.generateRookMap(Utils.getWhiteRook(status));
// remove own pieces
whiteRookAttack = ~(whites) & whiteRookAttack;
// remove moves behind pieces
whiteRookAttack = validateRookMoves(Utils.getWhiteRook(status), whiteRookAttack);
// save this state
whiteRookAttackReverify = whiteRookAttack;
// get map of attackable enemies
temp = whiteRookAttack & blacks; // remember placement of reachable blacks
// remove enemies
whiteRookAttack = ~(blacks) & whiteRookAttack;
// remove moves behind enemies
whiteRookAttack = validateRookMoves(Utils.getWhiteRook(status), whiteRookAttack);
// now add enemies back - we can attack them TODO bug! there are returned even unreachable enemies
whiteRookAttack |= temp;
// remove attacks on king's new moves y/n (n-ok, y-analyse)
if ((blackAttack & whiteKingAttack) != 0) { // TODO black attack can be eliminated
whiteKingAttack = whiteKingAttack & ~blackRookAttack;
whiteKingAttack = whiteKingAttack & ~blackKingAttack;
}
int movePointer = 0;
// MapGenerator.printMap(whiteRookAttack);
// System.out.println();
// MapGenerator.printMap(whiteKingAttack);
// System.out.println();
// MapGenerator.printMap(pawnAttack);
if (Utils.isChess(status)) {// we are shocked
if (color == Main.white) {
// generate
} else {
}
} else {// generate moves from maps
if (color == Main.white) {
for (int i = 0; i < 49; i++) {
// @TODO queen generation
if ((pawnAttack & 1) == 1) {// check if given move doesnt expose king to chess
if(reverifyRook(Utils.setWhiteRook(status, i), Main.white, whiteRookAttackReverify, blacks)){
moves[movePointer] = (Utils.setPieceMoveFrom(Utils.setPieceMoveTo(Utils.setPieceMoveKind(0, Main.pawn), i), Utils.getWhitePawn(status)));
movePointer++;
}
}
pawnAttack>>=1;
if ((whiteKingAttack & 1) == 1) {
// reverifyPawn(Utils.setWhitePawn(status, i), Main.white, pawnAttackReverify, blacks);
moves[movePointer] = (Utils.setPieceMoveFrom(Utils.setPieceMoveTo(Utils.setPieceMoveKind(0, Main.king), i), Utils.getWhiteKing(status)));
movePointer++;
}
whiteKingAttack>>=1;
if ((whiteRookAttack & 1) == 1) {
moves[movePointer] = (Utils.setPieceMoveFrom(Utils.setPieceMoveTo(Utils.setPieceMoveKind(0, Main.rook), i), Utils.getWhiteRook(status)));
movePointer++;
}
whiteRookAttack>>=1;
}
} else {
for (int i = 0; i < 49; i++) {
if ((blackKingAttack & 1) == 1) {
moves[movePointer] = (Utils.setPieceMoveFrom(Utils.setPieceMoveTo(Utils.setPieceMoveKind(0, Main.king), i), Utils.getBlackKing(status)));
movePointer++;
}
blackKingAttack>>=1;
if ((blackRookAttack & 1) == 1) {
if(reverifyRook(Utils.setBlackRook(status, i), Main.black, blackRookAttackReverify, whites)){
moves[movePointer] = (Utils.setPieceMoveFrom(Utils.setPieceMoveTo(Utils.setPieceMoveKind(0, Main.rook), i), Utils.getBlackRook(status)));
movePointer++;
}
}
blackRookAttack>>=1;
}
}
}
return moves;
}
/**
*
* @param status new status of chess board (move to verify)
* @param color of checked piece move
* @param rookAttackReverify (presaved validated moves without own pieces)
* @param enemyBits position of pieces of oposit color
* @return
*/
private boolean reverifyRook(int status, int color, long rookAttackReverify, long enemyBits) {
long temp = 0;
// get map of attackable enemies
temp = rookAttackReverify & enemyBits; // remember placement of reachable blacks
// remove enemies
rookAttackReverify = ~(enemyBits) & rookAttackReverify;
if(color == Main.white){
// remove moves behind enemies
rookAttackReverify = validateRookMoves(Utils.getWhiteRook(status), rookAttackReverify);
rookAttackReverify |= temp;
if((rookAttackReverify&Utils.setBit(Utils.getBlackKing(status), 0))==1)
return false; //king can be attacked after the move, this is not valid move
}else{
rookAttackReverify = validateRookMoves(Utils.getBlackRook(status), rookAttackReverify);
rookAttackReverify |= temp;
if((rookAttackReverify&Utils.setBit(Utils.getWhiteKing(status), 0))==1)
return false; //king can be attacked after the move, this is not valid move
}
return true;
}
/**
* @param rookPos - rooks position on chess board
* @param validRookAttack - rooks map without friendly pieces (zeros where friendly are placed)
* @return
*/
private long validateRookMoves(int rookPos, long validRookAttack) {
boolean clL, clR, clU, clD;
clL=clR=clU=clD=false;
int col = rookPos%Main.edgeSize;
int row = rookPos/Main.edgeSize;
// from the piece go to every direction,
//if 0 set flag and set all remaining fields in given direction to 0 too
for(int i=0; i<Main.edgeSize; i++){
//check direction down
if((i+row+1)<Main.edgeSize){
if(Utils.getBit(col+(i+row+1)*Main.edgeSize, validRookAttack)==0)
clD=true;
if(clD)
validRookAttack = Utils.clearBit(col+(i+row+1)*Main.edgeSize, validRookAttack);
}
//check direction up
if((row-i-1)>=0){
if(Utils.getBit(col+(row-i-1)*Main.edgeSize, validRookAttack)==0)
clU=true;
if(clU)
validRookAttack = Utils.clearBit(col+(row-i-1)*Main.edgeSize, validRookAttack);
}
//check direction left
if((col-i-1)>=0){
if(Utils.getBit(col-i-1+row*Main.edgeSize, validRookAttack)==0)
clL=true;
if(clL)
validRookAttack = Utils.clearBit(col-i-1+row*Main.edgeSize, validRookAttack);
}
//check direction right
if((col+i+1)<Main.edgeSize){
if(Utils.getBit(col+i+1+row*Main.edgeSize, validRookAttack)==0)
clR=true;
if(clR)
validRookAttack = Utils.clearBit(col+i+1+row*Main.edgeSize, validRookAttack);
}
}
return validRookAttack;
}
private int evaluate(int moves) {
if(moves == 0)
return Integer.MAX_VALUE;
else
return 0;
}
private void initData() throws Exception {
BufferedReader br = null;
if (local == true)
br = new BufferedReader(new FileReader("./test.in"));
else
br = new BufferedReader(new InputStreamReader(System.in));
wKing = kKing = wRook = kRook = wPawn = -1;
parseInput(br.readLine());
starts = br.readLine().startsWith("B") ? true : false;
horizont = Integer.parseInt(br.readLine());
//generate initial chessboard status
initStatus = Utils.setBlackKing(initStatus, kKing);
initStatus = Utils.setWhiteKing(initStatus, wKing);
if(wRook!=-1)
initStatus = Utils.setWhiteRook(initStatus, wRook);
if(kRook!=-1)
initStatus = Utils.setBlackRook(initStatus, kRook);
if(wPawn!=-1)
initStatus = Utils.setWhitePawn(initStatus, wPawn);
}
private static void parseInput(String readLine) {
String[] elements = readLine.split(" ");
for (int i = 0; i < elements.length; i++) {
if (elements[i].startsWith("K")) {
if (wKing != -1) {
kKing = Utils.pos2num(elements[i].substring(1));
} else {
wKing = Utils.pos2num(elements[i].substring(1));
}
} else if (elements[i].startsWith("V")) {
if (wRook != -1) {
kRook = Utils.pos2num(elements[i].substring(1));
} else {
wRook = Utils.pos2num(elements[i].substring(1));
}
} else {
wPawn = Utils.pos2num(elements[i]);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment