/*************************************************************************** * 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. * ***************************************************************************/ // // KCheckers Engine // // Internal: External: // // Board = 54 Fields: Board = 32 Fields: // // | 06 07 08 09| MAN2 | 00 01 02 03| // |11 12 13 14 | |04 05 06 07 | // | 17 18 19 20| | 08 09 10 11| // |22 23 24 25 | |12 13 14 15 | // | 28 29 30 31| | 16 17 18 19| // |33 34 35 36 | |20 21 22 23 | // | 39 40 41 42| | 24 25 26 27| // |44 45 46 47 | MAN1 |28 29 30 31 | #include #include #include #include "checkers.h" int Checkers::internal(int external) const { const int i[]={6,7,8,9,11,12,13,14,17,18,19,20,22,23,24,25, 28,29,30,31,33,34,35,36,39,40,41,42,44,45,46,47}; return i[external]; } /* int Checkers::external(int internal) const { const int i[]={ -1,-1,-1,-1,-1,-1,0,1,2,3, // 0-9 internal -1,4,5,6,7,-1,-1,8,9,10, // 10-19 11,-1,12,13,14,15,-1,-1,16,17, // 20-29 18,19,-1,20,21,22,23,-1,-1,24, // 30-39 25,26,27,-1,28,29,30,31,-1,-1, // 40-49 -1,-1,-1,-1}; // 50-53 return i[internal]; } */ Checkers::Checkers() { for(int i=0;i<54;i++) board[i] = NONE; for(int i=0; i<12; i++) board[internal(i)] = MAN2; for(int i=12; i<20; i++) board[internal(i)] = FREE; for(int i=20; i<32; i++) board[internal(i)] = MAN1; levelmax = 2; srand(time(0)); // Seed the random number generator } bool Checkers::setup(int setupboard[]) { /*aw - caused problems int sum1=0; // Sum of MAN1 & KING1 int sum2=0; // Sum of MAN2 & KING2 for(int i=0; i<32; i++) { switch(setupboard[i]) { case MAN1: case KING1: sum1++; break; case MAN2: case KING2: sum2++; break; case FREE: break; default: return false; } } if(sum1>12 || sum1==0 || sum2>12 || sum2==0) return false; for(int i=0; i<4; i++) if(setupboard[i]==MAN1) return false; for(int i=28; i<32; i++) if(setupboard[i]==MAN2) return false; */ for(int i=0; i<32; i++) board[internal(i)] = setupboard[i]; return true; } /////////////////////////////////////////////////// // // Player Functions // /////////////////////////////////////////////////// bool Checkers::checkMove1() const { for(int i=6;i<48;i++) if(checkMove1(i)) return true; return false; } bool Checkers::checkMove1(int i) const { switch(board[i]) { case MAN1: if(board[i-6]==FREE) return true; if(board[i-5]==FREE) return true; break; case KING1: if(board[i-6]==FREE) return true; if(board[i-5]==FREE) return true; if(board[i+5]==FREE) return true; if(board[i+6]==FREE) return true; } return false; } //////////////////////////////////////////////////// // // Computer Functions // //////////////////////////////////////////////////// void Checkers::go2() { // level=0; for(int i=6;i<48;i++) bestboard[i] = board[i]; turn(); for(int i=6;i<48;i++) board[i] = bestboard[i]; ; } void Checkers::turn(int& resMax, bool capture) { if(levelresMax) { resMax=res; if(level==1) { for(int i=6;i<48;i++) bestboard[i]=board[i]; bestcounter=1; } } else if(res==resMax && level==1) { bestcounter++; if((rand()%bestcounter)==0) { for(int i=6;i<48;i++) bestboard[i]=board[i]; } } if(capture) { if(f12) board[12]=NONE; if(f13) board[13]=NONE; if(f14) board[14]=NONE; if(f17) board[17]=NONE; if(f18) board[18]=NONE; if(f19) board[19]=NONE; if(f23) board[23]=NONE; if(f24) board[24]=NONE; if(f25) board[25]=NONE; if(f28) board[28]=NONE; if(f29) board[29]=NONE; if(f30) board[30]=NONE; if(f34) board[34]=NONE; if(f35) board[35]=NONE; if(f36) board[36]=NONE; if(f39) board[39]=NONE; if(f40) board[40]=NONE; if(f41) board[41]=NONE; } } else if(resMax<0) resMax=0; } bool Checkers::checkMove2() const { for(int i=6;i<48;i++) { switch(board[i]) { case MAN2: if(board[i+5]==FREE) return true; if(board[i+6]==FREE) return true; break; case KING2: if(board[i-6]==FREE) return true; if(board[i-5]==FREE) return true; if(board[i+5]==FREE) return true; if(board[i+6]==FREE) return true; } } return false; } int Checkers::turn() { int resMax=(level-levelmax)*10; level++; if(checkCapture2()) { for(int i=6; i<48; i++) { switch(board[i]) { case MAN2: manCapture2(i, resMax); break; case KING2: kingCapture2(i,UL,resMax); kingCapture2(i,UR,resMax); kingCapture2(i,DL,resMax); kingCapture2(i,DR,resMax); } } } else if(checkMove2()) { for(int i=6;i<48;i++) { switch(board[i]) { case MAN2: if(board[i+5]==FREE) { // down left board[i]=FREE; if(i>38) board[i+5]=KING2; else board[i+5]=MAN2; turn(resMax); board[i+5]=FREE; board[i]=MAN2; } if(board[i+6]==FREE) { // down right board[i]=FREE; if(i>38) board[i+6]=KING2; else board[i+6]=MAN2; turn(resMax); board[i+6]=FREE; board[i]=MAN2; } break; case KING2: kingMove2(i,resMax); break; } } } else ; level--; return resMax; } QString Checkers::toString(bool rotate) const { int fields[32]; int it; for(int i=0; i<32; i++) { it = item(i); if(rotate) fields[31-i] = (~it&7)-1; else fields[i] = it; } QString str; for(int i=0; i<32; i++) str += QString("").sprintf("%.2u", fields[i]); return str; } bool Checkers::fromString(const QString& str) { int fields[32]; for(int i=0; i<32; i++) fields[i] = str.mid(i*2, 2).toInt(); // apply if(!setup(fields)) { qDebug() << "Checkers::fromString:" << str; return false; } return true; }