mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-15 10:54:22 -05:00
554 lines
15 KiB
C++
554 lines
15 KiB
C++
|
/***************************************************************************
|
||
|
* 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;
|
||
|
}
|
||
|
|
||
|
|