/*************************************************************************** * Copyright (C) 2002-2003 Andi Peredri * * andi@ukr.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ // // Russian Checkers #include "rcheckers.h" /////////////////////////////////////////////////// // // Player Functions // /////////////////////////////////////////////////// bool RCheckers::go1(int from,int field) { from=internal(from); field=internal(field); to=field; if(checkCapture1()) { bool capture=false; switch(board[from]) { case MAN1: if(manCapture1(from,UL,capture)) return true; if(manCapture1(from,UR,capture)) return true; if(manCapture1(from,DL,capture)) return true; if(manCapture1(from,DR,capture)) return true; return false; case KING1: if(kingCapture1(from,UL,capture)) return true; if(kingCapture1(from,UR,capture)) return true; if(kingCapture1(from,DL,capture)) return true; if(kingCapture1(from,DR,capture)) return true; return false; } } else { switch(board[from]) { case MAN1: if((to==(from-6))||(to==(from-5))) { board[from]=FREE; if(to<10) board[to]=KING1; else board[to]=MAN1; return true; } return false; case KING1: for(int i=from-6;;i-=6) { if(i==to) { board[from]=FREE; board[to]=KING1; return true; } else if(board[i]==FREE) continue; else break; } for(int i=from-5;;i-=5) { if(i==to) { board[from]=FREE; board[to]=KING1; return true; } else if(board[i]==FREE) continue; else break; } for(int i=from+5;;i+=5) { if(i==to) { board[from]=FREE; board[to]=KING1; return true; } else if(board[i]==FREE) continue; else break; } for(int i=from+6;;i+=6) { if(i==to) { board[from]=FREE; board[to]=KING1; return true; } else if(board[i]==FREE) continue; else break; } return false; } } return false; } bool RCheckers::checkCapture1() const { for(int i=6;i<48;i++) if(checkCapture1(i)) return true; return false; } bool RCheckers::checkCapture1(int i) const { switch(board[i]) { case MAN1: if(board[i-6]==MAN2 || board[i-6]==KING2) if(board[i-12]==FREE) return true; if(board[i-5]==MAN2 || board[i-5]==KING2) if(board[i-10]==FREE) return true; if(board[i+5]==MAN2 || board[i+5]==KING2) if(board[i+10]==FREE) return true; if(board[i+6]==MAN2 || board[i+6]==KING2) if(board[i+12]==FREE) return true; break; case KING1: int k; for(k=i-6;board[k]==FREE;k-=6); if(board[k]==MAN2 || board[k]==KING2) if(board[k-6]==FREE) return true; for(k=i-5;board[k]==FREE;k-=5); if(board[k]==MAN2 || board[k]==KING2) if(board[k-5]==FREE) return true; for(k=i+5;board[k]==FREE;k+=5); if(board[k]==MAN2 || board[k]==KING2) if(board[k+5]==FREE) return true; for(k=i+6;board[k]==FREE;k+=6); if(board[k]==MAN2 || board[k]==KING2) if(board[k+6]==FREE) return true; } return false; } /* ORIG func aw bool RCheckers::checkCapture1() { for(int i=6;i<48;i++) { switch(board[i]) { case MAN1: if(board[i-6]==MAN2 || board[i-6]==KING2) if(board[i-12]==FREE) return true; if(board[i-5]==MAN2 || board[i-5]==KING2) if(board[i-10]==FREE) return true; if(board[i+5]==MAN2 || board[i+5]==KING2) if(board[i+10]==FREE) return true; if(board[i+6]==MAN2 || board[i+6]==KING2) if(board[i+12]==FREE) return true; break; case KING1: int k; for(k=i-6;board[k]==FREE;k-=6); if(board[k]==MAN2 || board[k]==KING2) if(board[k-6]==FREE) return true; for(k=i-5;board[k]==FREE;k-=5); if(board[k]==MAN2 || board[k]==KING2) if(board[k-5]==FREE) return true; for(k=i+5;board[k]==FREE;k+=5); if(board[k]==MAN2 || board[k]==KING2) if(board[k+5]==FREE) return true; for(k=i+6;board[k]==FREE;k+=6); if(board[k]==MAN2 || board[k]==KING2) if(board[k+6]==FREE) return true; } } return false; } */ // Return TRUE if a course of the player true // Return FALSE if a course of the player incorrect bool RCheckers::manCapture1(int from,int direction,bool &capture) { int i=from+direction; if(board[i]==MAN2 || board[i]==KING2) { int k=i+direction; if(board[k]==FREE) { bool next=false; int save=board[i]; board[from]=FREE; board[i]=NONE; if(k<10) { board[k]=KING1; if(kingCapture1(k,direction+11,next)) { board[i]=FREE; return true; } } else { board[k]=MAN1; if(direction==UL || direction==DR) { if(manCapture1(k,UR,next)) {board[i]=FREE;return true;} if(manCapture1(k,DL,next)) {board[i]=FREE;return true;} } else { if(manCapture1(k,UL,next)) {board[i]=FREE;return true;} if(manCapture1(k,DR,next)) {board[i]=FREE;return true;} } if(manCapture1(k,direction,next)) {board[i]=FREE;return true;} } if((!next) && k==to) {board[i]=FREE;return true;} board[k]=FREE; board[i]=save; board[from]=MAN1; capture=true; } } return false; } bool RCheckers::kingCapture1(int from,int direction,bool &capture) { int i; for(i=from+direction;board[i]==FREE;i+=direction); if(board[i]==MAN2 || board[i]==KING2) { int k=i+direction; if(board[k]==FREE) { bool next=false; int save=board[i]; board[from]=FREE; board[i]=NONE; for(;board[k]==FREE;k+=direction) { board[k]=KING1; if(direction==UL || direction==DR) { if(kingCapture1(k,UR,next)) {board[i]=FREE;return true;} if(kingCapture1(k,DL,next)) {board[i]=FREE;return true;} } else { if(kingCapture1(k,UL,next)) {board[i]=FREE;return true;} if(kingCapture1(k,DR,next)) {board[i]=FREE;return true;} } board[k]=FREE; } board[k-=direction]=KING1; if(kingCapture1(k,direction,next)) {board[i]=FREE;return true;} board[k]=FREE; if(!next) for(;k!=i;k-=direction) if(k==to) {board[i]=FREE;board[k]=KING1;return true;} board[i]=save; board[from]=KING1; capture=true; } } return false; } //////////////////////////////////////////////////// // // Computer Functions // //////////////////////////////////////////////////// void RCheckers::kingMove2(int from,int &resMax) { board[from]=FREE; for(int i=from-6;board[i]==FREE;i-=6) { board[i]=KING2; turn(resMax); board[i]=FREE; } for(int i=from-5;board[i]==FREE;i-=5) { board[i]=KING2; turn(resMax); board[i]=FREE; } for(int i=from+5;board[i]==FREE;i+=5) { board[i]=KING2; turn(resMax); board[i]=FREE; } for(int i=from+6;board[i]==FREE;i+=6) { board[i]=KING2; turn(resMax); board[i]=FREE; } board[from]=KING2; } bool RCheckers::checkCapture2() const { for(int i=6;i<48;i++) { switch(board[i]) { case MAN2: if(board[i-6]==MAN1 || board[i-6]==KING1) if(board[i-12]==FREE) return true; if(board[i-5]==MAN1 || board[i-5]==KING1) if(board[i-10]==FREE) return true; if(board[i+5]==MAN1 || board[i+5]==KING1) if(board[i+10]==FREE) return true; if(board[i+6]==MAN1 || board[i+6]==KING1) if(board[i+12]==FREE) return true; break; case KING2: int k; for(k=i-6;board[k]==FREE;k-=6); if(board[k]==MAN1 || board[k]==KING1) if(board[k-6]==FREE) return true; for(k=i-5;board[k]==FREE;k-=5); if(board[k]==MAN1 || board[k]==KING1) if(board[k-5]==FREE) return true; for(k=i+5;board[k]==FREE;k+=5); if(board[k]==MAN1 || board[k]==KING1) if(board[k+5]==FREE) return true; for(k=i+6;board[k]==FREE;k+=6); if(board[k]==MAN1 || board[k]==KING1) if(board[k+6]==FREE) return true; } } return false; } // Return TRUE if it is possible to capture // Return FALSE if it is impossible to capture bool RCheckers::manCapture2(int from,int &resMax) { bool capture=false; int i=from-6; if(board[i]==MAN1 || board[i]==KING1) { int k=from-12; if(board[k]==FREE) { int save=board[i]; board[from]=FREE; board[i]=NONE; board[k]=MAN2; resMax--; if(!manCapture2(k,resMax)) turn(resMax,true); resMax++; board[k]=FREE; board[i]=save; board[from]=MAN2; capture=true; } } i=from-5; if(board[i]==MAN1 || board[i]==KING1) { int k=from-10; if(board[k]==FREE) { int save=board[i]; board[from]=FREE; board[i]=NONE; board[k]=MAN2; resMax--; if(!manCapture2(k,resMax)) turn(resMax,true); resMax++; board[k]=FREE; board[i]=save; board[from]=MAN2; capture=true; } } i=from+5; if(board[i]==MAN1 || board[i]==KING1) { int k=from+10; if(board[k]==FREE) { int save=board[i]; board[from]=FREE; board[i]=NONE; resMax--; if(from>32) { board[k]=KING2; if(!kingCapture2(k,UL,resMax)) turn(resMax,true); } else { board[k]=MAN2; if(!manCapture2(k,resMax)) turn(resMax,true); } resMax++; board[k]=FREE; board[i]=save; board[from]=MAN2; capture=true; } } i=from+6; if(board[i]==MAN1 || board[i]==KING1) { int k=from+12; if(board[k]==FREE) { int save=board[i]; board[from]=FREE; board[i]=NONE; resMax--; if(from>32) { board[k]=KING2; if(!kingCapture2(k,UR,resMax)) turn(resMax,true); } else { board[k]=MAN2; if(!manCapture2(k,resMax)) turn(resMax,true); } resMax++; board[k]=FREE; board[i]=save; board[from]=MAN2; capture=true; } } if(capture) return true; return false; } bool RCheckers::kingCapture2(int from,int direction,int &resMax) { int i; for(i=from+direction;board[i]==FREE;i+=direction); if(board[i]==MAN1 || board[i]==KING1) { int k=i+direction; if(board[k]==FREE) { bool capture=false; int save=board[i]; board[from]=FREE; board[i]=NONE; resMax--; for(;board[k]==FREE;k+=direction) { board[k]=KING2; if(direction==UL || direction==DR) { if(kingCapture2(k,UR,resMax)) capture=true; if(kingCapture2(k,DL,resMax)) capture=true; } else { if(kingCapture2(k,UL,resMax)) capture=true; if(kingCapture2(k,DR,resMax)) capture=true; } board[k]=FREE; } board[k-=direction]=KING2; if(kingCapture2(k,direction,resMax)) capture=true; board[k]=FREE; if(!capture) for(;k!=i;k-=direction) { board[k]=KING2; turn(resMax,true); board[k]=FREE; } resMax++; board[i]=save; board[from]=KING2; return true; } } return false; }