RetroShare/plugins/qcheckers_plugin/checkers.cc

452 lines
12 KiB
C++
Raw Normal View History

/***************************************************************************
* 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 <time.h>
#include <stdlib.h>
#include <QDebug>
#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(level<levelmax) {
bool f12, f13, f14, f17, f18, f19, f23, f24, f25;
bool f28, f29, f30, f34, f35, f36, f39, f40, f41;
f12 = f13 = f14 = f17 = f18 = f19 = f23 = f24 = f25 = false;//for gcc
f28 = f29 = f30 = f34 = f35 = f36 = f39 = f40 = f41 = false;//for gcc
if(capture) {
if(board[12]==NONE) {f12=true; board[12] = FREE;} else f12=false;
if(board[13]==NONE) {f13=true; board[13] = FREE;} else f13=false;
if(board[14]==NONE) {f14=true; board[14] = FREE;} else f14=false;
if(board[17]==NONE) {f17=true; board[17] = FREE;} else f17=false;
if(board[18]==NONE) {f18=true; board[18] = FREE;} else f18=false;
if(board[19]==NONE) {f19=true; board[19] = FREE;} else f19=false;
if(board[23]==NONE) {f23=true; board[23] = FREE;} else f23=false;
if(board[24]==NONE) {f24=true; board[24] = FREE;} else f24=false;
if(board[25]==NONE) {f25=true; board[25] = FREE;} else f25=false;
if(board[28]==NONE) {f28=true; board[28] = FREE;} else f28=false;
if(board[29]==NONE) {f29=true; board[29] = FREE;} else f29=false;
if(board[30]==NONE) {f30=true; board[30] = FREE;} else f30=false;
if(board[34]==NONE) {f34=true; board[34] = FREE;} else f34=false;
if(board[35]==NONE) {f35=true; board[35] = FREE;} else f35=false;
if(board[36]==NONE) {f36=true; board[36] = FREE;} else f36=false;
if(board[39]==NONE) {f39=true; board[39] = FREE;} else f39=false;
if(board[40]==NONE) {f40=true; board[40] = FREE;} else f40=false;
if(board[41]==NONE) {f41=true; board[41] = FREE;} else f41=false;
}
int b6=board[6];
int b7=board[7];
int b8=board[8];
int b9=board[9];
int b11=board[11];
int b12=board[12];
int b13=board[13];
int b14=board[14];
int b17=board[17];
int b18=board[18];
int b19=board[19];
int b20=board[20];
int b22=board[22];
int b23=board[23];
int b24=board[24];
int b25=board[25];
int b28=board[28];
int b29=board[29];
int b30=board[30];
int b31=board[31];
int b33=board[33];
int b34=board[34];
int b35=board[35];
int b36=board[36];
int b39=board[39];
int b40=board[40];
int b41=board[41];
int b42=board[42];
int b44=board[44];
int b45=board[45];
int b46=board[46];
int b47=board[47];
board[6]=FULL-b47;
board[7]=FULL-b46;
board[8]=FULL-b45;
board[9]=FULL-b44;
board[11]=FULL-b42;
board[12]=FULL-b41;
board[13]=FULL-b40;
board[14]=FULL-b39;
board[17]=FULL-b36;
board[18]=FULL-b35;
board[19]=FULL-b34;
board[20]=FULL-b33;
board[22]=FULL-b31;
board[23]=FULL-b30;
board[24]=FULL-b29;
board[25]=FULL-b28;
board[28]=FULL-b25;
board[29]=FULL-b24;
board[30]=FULL-b23;
board[31]=FULL-b22;
board[33]=FULL-b20;
board[34]=FULL-b19;
board[35]=FULL-b18;
board[36]=FULL-b17;
board[39]=FULL-b14;
board[40]=FULL-b13;
board[41]=FULL-b12;
board[42]=FULL-b11;
board[44]=FULL-b9;
board[45]=FULL-b8;
board[46]=FULL-b7;
board[47]=FULL-b6;
int res=-turn();
board[6]=b6;
board[7]=b7;
board[8]=b8;
board[9]=b9;
board[11]=b11;
board[12]=b12;
board[13]=b13;
board[14]=b14;
board[17]=b17;
board[18]=b18;
board[19]=b19;
board[20]=b20;
board[22]=b22;
board[23]=b23;
board[24]=b24;
board[25]=b25;
board[28]=b28;
board[29]=b29;
board[30]=b30;
board[31]=b31;
board[33]=b33;
board[34]=b34;
board[35]=b35;
board[36]=b36;
board[39]=b39;
board[40]=b40;
board[41]=b41;
board[42]=b42;
board[44]=b44;
board[45]=b45;
board[46]=b46;
board[47]=b47;
if(res>resMax) {
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;
}