Created
December 7, 2010 20:28
-
-
Save dizzi/732350 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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