string pin, checks, list;

checks = whitecheck(kingsq);
pin = whitepin(kingsq);
list = whitelist(checks, pin, wkbool, wqbool, enpassant)

i wrote a chess program in VB6 and have finished converting it to C++.

however everytime pin or checks is not a null string it throws a GPF.

how can i pass the strings into the list function without throwing a gpf??

checks and pin are strings

>>everytime pin or checks is not a null string it throws a GPF.

>>checks and pin are strings

Do you mean std::string declared in <string> header file? Those are not null-terminated strings at all but c++ class.

Post the function prototype for whitelist(checks, pin, wkbool, wqbool, enpassant)

string whitelist(string checks, string pins, bool wKingSide, bool wQueenSide, string enp)

when the strings contain characters it throws a GPF,
pin == ""
ok
pin == "h5f7"
fault

Learn to use your compiler's debugger and single-step through your program to see what is happening. The problem could be in whitelist() function or somewhere before that function is called. Its impossible for anyone to analyze your program without seeing the code.

I HAVE STEPPED THROUGH THE PROGRAM

as soon as the string is passed into the function it ends
theres nothing wrong with the other functions.

string f;
string g;
string list;

if (onmove == "w") {
        f = checkwhite(wkingsq, wkingsq);
        g = whitepin(wkingsq);
        list = whitelist(f, g, wkside, wqside, "");
}
else
{
        f = checkblack(bkingsq, bkingsq);
        g = blackpin(bkingsq);
        list = blacklist(f, g, bkside, bqside, "");
}

here is the source

I have since modified the string to global and no longer terminates.
it is about 42 pages of code, very long.

#include<iostream>
#include<string>
#include<stdio>
#include<stdlib>
#include<limits>
#include<time>


using namespace std;


const int horiz = 0;
const int verti = 1;
const int diagonal1 = 2;
const int diagonal2 = 3;

const int pawn = 100;
const int bishop = 305;
const int knight = 300;
const int rook = 500;
const int queen = 900;
const int king = 2000;

string gpins, gchecks;
int board[64];
int wkingsq, bkingsq;

bool wkside, wqside, bkside, bqside;

string onmove;



int putab(int a, int b)
{
  int i;
  i = a + b*8;
	return i;
}

int char2promote(string a, string b){
int out1;
 char aa;
 aa = (char) a[0];
switch (aa){
case 'q':
out1 = queen;
break;
case 'r':
out1 = rook;
break;
case 'b':
out1 = bishop;
break;
case 'n':
out1 = knight;
break;
}
if (b == "b") out1 *= -1;
return out1;
}


string chfile(int x){
  static string cho;
 switch(x){
 case 0:
 cho = "a";
 break;
 case 1:
 cho = "b";
 break;
 case 2:
 cho = "c";
 break;
 case 3:
 cho = "d";
 break;
 case 4:
 cho = "e";
 break;
 case 5:
 cho = "f";
 break;
 case 6:
 cho = "g";
 break;
 case 7:
 cho = "h";
 break;

 }
 return cho;
}



string chrank(int x){
  static string cho;
 switch(x){
 case 0:
 cho = "1";
 break;
 case 1:
 cho = "2";
 break;
 case 2:
 cho = "3";
 break;
 case 3:
 cho = "4";
 break;
 case 4:
 cho = "5";
 break;
 case 5:
 cho = "6";
 break;
 case 6:
 cho = "7";
 break;
 case 7:
 cho = "8";
 break;

 }
 return cho;
}


int bounds (int a, int b)
{
if ((a >= 0) && (a <= 7) && (b >= 0) && (b <= 7))
{
return true;
}
else
{
return false;
}
}

const startup[64] = { rook, knight, bishop, queen, king, bishop, knight, rook, pawn, pawn,pawn,pawn,pawn,pawn,pawn, pawn, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -pawn, -pawn, -pawn, -pawn, -pawn, -pawn, -pawn, -pawn, -rook, -knight, -bishop, -queen, -king, -bishop, -knight, -rook};

const ncenter[64]= {-20, 0, 0, 0, 0, 0, 0, -20,  0, 1, 1, 1, 1, 1, 1, 0,  0, 1, 2, 2 , 2, 2, 1, 0,    0, 1, 2, 2 , 2, 2, 1, 0,  0, 1, 2, 2 , 2, 2, 1, 0,  0, 1, 2, 2 , 2, 2, 1, 0,  0, 1, 1, 1, 1, 1, 1, 0, -20, 0, 0, 0, 0, 0, 0, -20   } ;

void setup (void);

 int geta(int a){
//get file 0 - 7
int i;
i = int(a % 8);
return i;
}

int getb(int a){
//get rank 0 - 7
int i;
i = int(a/8);
return i;
}

int str2num(string f1)
{

int aa, bb;
 switch (f1[0]){
 case 'a':
 aa = 0;
 break;
 case 'b':
 aa = 1;
 break;
 case 'c':
 aa = 2;
 break;
 case 'd':
 aa = 3;
 break;
 case 'e':
 aa = 4;
 break;
 case 'f':
 aa = 5;
 break;
 case 'g':
 aa = 6;
 break;
 case 'h':
 aa = 7;
 break;
 }

 switch (f1[1]){
 case '1':
 bb = 0;
 break;
 case '2':
 bb = 1;
 break;
 case '3':
 bb = 2;
 break;
 case '4':
 bb = 3;
 break;
 case '5':
 bb = 4;
 break;
 case '6':
 bb = 5;
 break;
 case '7':
 bb = 6;
 break;
 case '8':
 bb = 7;
 break;
 }

return aa + bb*8;

}

string coord2(int c){
 int a, b;
 static string e, f;
 

 a = geta(c);
 b = getb(c);
 e = chfile(a);
 f = chrank(b);
 e += f;

 return e;
 }
string checkblack(int, int);



int sgn(int h){
 if (h > 0) {return 1;}
 if (h < 0) {return -1;}
 return 0;
}






void setup (void) {
int i;
	for (i = 0; i < 64; i++){
	board[i] = startup[i]; //setup starting position
	}
  onmove = "w";
  
  wkside = true;
  wqside = true;
  bkside = true;
  bqside = true;

  wkingsq = 4;
  bkingsq = 60;
}



string checkblack(int ksq, int remv){
	int checklist[9];
	int a, b, c, d, e, f, g, num, x;
	num = 0;
	int repl;

	if (remv != 64) {

	repl = board[remv];
	board[remv] = 0;

	}

	static string freturn;

 }

string checkwhite(int ksq, int remv){
	int checklist[9];
	int a, b, c, d, e, f, g, num, x;
	int repl;
	num = 0;
	static string freturn;

	if (remv != 64) {

	repl = board[remv];
	board[remv] = 0;

	}

 return freturn;
 }





int getplane(int c, int d){
if (c == 0 && d <= -1 ) { return verti;}
if (c <= -1 && d == 0 ) { return horiz;}
if (c >= 1 && d == 0 ) { return horiz;}
if (c >= 1 && d <= -1 ) { return diagonal1;}
if (c <= -1 && d <= -1 ) { return diagonal2;}
if (c == 0 && d >= 1 ) { return verti;}
if (c <= -1 && d >= 1 ) { return diagonal1;}
if (c >= 1 && d >= 1 ) { return diagonal2;}
return 0;
}

int comparePlane(int square1, int square2)  {
int a, b, c, d, e, f, g, x, y;
a = geta(square1);
b = getb(square1);
c = geta(square2);
d = getb(square2);
x = a - c;
e = sgn(x);
y = b - d;
f = sgn(y);
g = getplane(e, f);
return g;
}


string whitepin(int ksq) {
	  int pinner[8];
	  int pinned[8];

	  int foundpiece, piecepinned;

	  if (ksq == 64) return "";

	  int numpins = 0;
	  int a, b, c, d, e, f, g, h, x;

	  a = geta(ksq);
	  b = getb(ksq);

           string fi;
	  return fi;
 }

string blackpin(int ksq) {
	  int pinner[8];
	  int pinned[8];

	  int foundpiece, piecepinned;

	  if (ksq == 64) return '\x0';

	  int numpins = 0;
	  int a, b, c, d, e, f, g, h, x;

	  a = geta(ksq);
	  b = getb(ksq);

	 string fi;

	  return fi;
 }





	  string whiteRescue(int ksq)
	  {
			// a sub to find interposition or capture (of checking piece) when white is in check
			int checklist[8];

		  int a, b, c, d, e, f, g, x, i;
		  int	num = 0;

			a = geta(ksq);
			b = getb(ksq);


                        string ff;

			return ff;

	  }





string whitelist(string checks, string pins, bool wKingSide, bool wQueenSide, string enp)
	  {
			int fromSQ[218];
			int toSQ[218];
			int listA[9];
			int ListB[9];
			int epQ = 0;
			int a = 0;
			int b = 0;
			int c = 0;
			int d = 0;
			int e = 0;
			int f = 0;
			int g = 0;
			int i = 0;
			int x = 0;
			int z = 0;

			int zz = 0;
			int z2 = 0;
			int g2 = 0;
            bool mustcompare;
			static string ff, gg, nf, h;
			int kingSQ, pieceCheck;
checks = gchecks;
pins = gpins;
                          
			return ff;
	  }


string blackRescue (int q)
{
  int checklist[9];
  string ff;

  int num;
  int a, b, c, d, e, f, g, x, i;
  num = 0;
  a=geta(q);
  b=getb(q);
  int qq;
  
  return ff;
}

string blacklist (string checks, string pins, bool bKingSide, bool bQueenSide, string enp)
{

  static  int  fromSQ[180];
  static  int  toSQ[180];
  static  int  listA[8];
  static  int  epQ;
  static  int  ListB[8];
  static  int  a;
  static  int  b;
  static  int  c;
  static  int  d;
  static  int  e;
  static  int  f;
  static  int  g;
  static  int  i;
  static  int  X;
  static  int  z;

  static  int  zz;
  static  int  z2;
  static  int  g2;
  static string ff, gg, nf;
  bool mustCompare;


  int kingSQ, pieceCheck;



  return ff;
}

string b2char (int in1){
 string ch;
 switch  (in1){
  case 0:
  ch = " ";
  break;
  case pawn:
  ch = "P";
  break;
  case knight:
  ch = "N";
  break;
  case bishop:
  ch = "B";
  break;
  case rook:
  ch = "R";
  break;
  case queen:
  ch = "Q";
  break;
  case king:
  ch = "K";
  break;
  case -pawn:
  ch = "p";
  break;
  case -knight:
  ch = "n";
  break;
  case -bishop:
  ch = "b";
  break;
  case -rook:
  ch = "r";
  break;
  case -queen:
  ch = "q";
  break;
  case -king:
  ch = "k";
  break;
  }
 return ch;
}



/* ########################  Main  ####################################### */

int main (void) {
using namespace std;
srand ( time(NULL) );

string passd;
bool usebook = true;
//passd.resize(1000);
// cout << "id Blitz Partner 2.0.01 " << endl;
// cout << "id author avery chicoine " << endl;
// cout << "uciok" << endl;

//cout.setf (ios::unitbuf);

while (1){
	getline (cin, passd );
        //cin.getline(passd, 100);
        //cout << '\n' << passd;
		  //fflush(stdout);
if (passd == "uci\x0" )
{
	cout << "id name averychess 1.0 " << endl;
	cout << "id author avery chicoine " << endl;
        cout << "option name internal book type check default true" << endl;
        cout << "option name UCI_EngineAbout type string default http://www3.telus.net/public/deepglue/" << endl;
	cout << "uciok" << endl;
}
if (passd == "ucinewgame\x0")
{
	setup;
}


if (passd == "isready\x0") {
cout << "readyok" << endl;
}
if (passd ==  "setoption name internal book value false\x0"){
usebook = false;
cout << "info internal book off" << endl;
}
if (passd ==  "setoption name internal book value true\x0"){
usebook = true;
cout << "info internal book on" << endl;
}
if (passd == "quit\x0")   {
cout << "Goodbye !!" << endl << "Thankyou for Playing Blitz Partner 2.0";
goto end1;
}
if (passd.substr(0, 2) == "go"){
string f, g, list;

 if (onmove == "w") {
f.clear();
g.clear();
        gchecks = checkwhite(wkingsq, wkingsq);
        gpins = whitepin(wkingsq);
        list = whitelist(f, g, wkside, wqside, "");
 }
 else
 {
f.clear();
g.clear();
        gchecks = checkblack(bkingsq, bkingsq);
        gpins = blackpin(bkingsq);
        cout << gchecks << '\n' << gpins << '\n';
        list = blacklist(f, g, bkside, bqside, "");
 }
int x, m;
string move1;
x = list.length();
if (x == 0 ) goto noplay;
x = x / 5;

m = rand() % x;
m *= 5;



move1 = list.substr(m, 4);

cout << "bestmove " << move1 << '\n';
 noplay:
}
if (passd.substr(0,17) == "position startpos"  && passd.length() <= 18) {
setup();
}


// -> position startpos moves etc...
if (passd.substr(0, 23) == "position startpos moves")   {
int imax, i;
int i1, i2;
setup();
imax = passd.length();
 for (i = 24; i < imax; i +=5 )
        {
           i1 = str2num(passd.substr(i, 2));
           i2 = str2num(passd.substr(i + 2, 2));
                 if (board[i1] == king && i1 == 4 && i2 == 6){   // castling white kingside
                   board[7] = 0;
                   board[5] = rook;
                 }
                 if (board[i1] == king && i1 == 4 && i2 == 2){   // castling white queenside
                   board[0] = 0;
                   board[3] = rook;
                 }
                 if (board[i1] == -king && i1 == 60 && i2 == 62){ // castling black kingside
                   board[63] = 0;
                   board[61] = -rook;
                 }
                 if (board[i1] == -king && i1 == 60 && i2 == 58){ // castling black queenside
                   board[56] = 0;
                   board[59] = -rook;
                 }
            switch (i1){    // Rook and King moves break castling
             case 0:
             wqside = false;
             break;
             case 7:
             wkside = false;
             break;
             case 56:
             bqside = false;
             break;
             case 63:
             bkside = false;
             break;
             case 4:
             wkside = false;
             wqside = false;
             break;
             case 60:
             bkside = false;
             bqside = false;
             break;
            }
             switch (i2){
             case 0:
             wqside = false;
             break;
             case 7:
             wkside = false;
             break;
             case 56:
             bqside = false;
             break;
             case 63:
             bkside = false;
             break;

            }

           board[i2] = board[i1];
           // board[36]
           board[i1] = 0;
           if (board[i2] == -king) bkingsq = i2;
           if (board[i2] == king) wkingsq =i2;
           string str;
           str = passd.substr(i + 4, 1);
           if (str != " " && !str.empty()){

            board[i2] = char2promote( passd.substr(i + 4, 1), onmove);
            i++;        // extra character in sequence.
           }

           if (onmove == "w"){ onmove = "b"; }else {onmove = "w";}
        }

string f;
string g;
string list;

f.clear();
g.clear();
if (onmove == "w") {
        gchecks = checkwhite(wkingsq, wkingsq);
        gpins = whitepin(wkingsq);
        list = whitelist(f, g, wkside, wqside, "");
}
else
{
        gchecks = checkblack(bkingsq, bkingsq);
        gpins = blackpin(bkingsq);
        list = blacklist(f, g, bkside, bqside, "");
}

//cout << "startpos" << endl << f << endl << g << endl << list ;

}


}
end1:
 return 0;
}

if you compile and run it under C++ Builder 6

It runs into the same problem.

Apparently the GPF program Termination is not happening for the reason I previously thought.

with the 8 major functions left empty its still happening.

compile this to .exe and run it

position startpos moves f2f4 d7d5 g1f3 b8c6 c2c3 f7f6 d2d3 e7e5 f4e5 f6e5 b1d2 g8f6 e2e4 f8c5 d2b3 c5b6 d1e2 e8g8 c1e3 d5d4 e3f2 f6g4 f2g3 d4c3 b2c3 g4e3 f3e5 c6e5 g3e5 c8g4 e2d2 d8e7 e5d4 b6d4 b3d4 e3f1 h1f1 f8f1 e1f1 a8f8 f1g1 e7g5 d2g5
and hit enter

type:
go wtime 680000 btime 660000 winc 20000 binc 20000
and hit enter

Now here it still GPF and terminates abnormally.
Therefore the error is being caused somewhere in int main().
more specifically i think it's a instance where the string passd; is being read passed it's length.

That narrows it down quite signifigantly,
in my VB6 version of this program i found the problem and fixed which vb6 program is almost word for word translation of this one with the exception of int main().

(So i suppose i could just can int main() in the cpp version and translate word for word the VB6 version to cpp.)

Except I am too lazy :D

I tried to compile using VC+ 2008 Express:

your program has a lot of unused variables that you need to clean up to prevent millions of warnings about it.

It also contains a couple real syntax errors. But you probably missed your compiler's error messages with all those warnings about unused variables.

line 556: what is setup ?

line 608: wnat is noplay ?

[edit]Ok noplay is a label. But you can get rid of it by removing the goto statement.

function checkblack() does not return a string. That could be a huge problem for anything calling that function.

If you're talking about the C++ class basic_string then you can just pass a string to a function in the same way as you're doing with a normal variable :) ...

e.g.:

void strFunc([B]string s[/B])
{
    cout << s << endl;
}

I tried to compile using VC+ 2008 Express:

your program has a lot of unused variables that you need to clean up to prevent millions of warnings about it.

It also contains a couple real syntax errors. But you probably missed your compiler's error messages with all those warnings about unused variables.

line 556: what is setup ?

line 608: wnat is noplay ?

[edit]Ok noplay is a label. But you can get rid of it by removing the goto statement.

function checkblack() does not return a string. That could be a huge problem for anything calling that function.

setup(); is a function that resets the board to the starting position,
puts pieces and pawns on their home squares, resets castling for white and black and set onmove = 'w' meaning white to move.

setup(); is called when the command 'ucinewgame' is recieved.

this is a chess playing program that comesin console form. UCI.

It parses the moves input after 'position startpos moves e2e4 etc etc..'

noplay: is a label for goto,
when the string ends with 'position startpos' it means no moves have yet been played from the start position . so no need to parse any moves hence goto noplay:

Can i change the title of this topic?
(at first i thought i was sending strings the wrong way because thats when it was GPFing, but i realize that in C++ program termination can happen long after a array index is out of bounds)

The actual problem has nothing to do with string passing at all.

The problem is between line 618 and line 693
where the string imax is being searched farther than it physically can.

Which is why its playing fine most of the time.

I tried to compile using VC+ 2008 Express:

your program has a lot of unused variables that you need to clean up to prevent millions of warnings about it.

It also contains a couple real syntax errors. But you probably missed your compiler's error messages with all those warnings about unused variables.

line 556: what is setup ?

line 608: wnat is noplay ?

[edit]Ok noplay is a label. But you can get rid of it by removing the goto statement.

function checkblack() does not return a string. That could be a huge problem for anything calling that function.

The unused variables are used in the whole program each of those functions are several hundred lines long.

But I dont think daniweb will let me post 42000 lines of code.

..and it also demonstrates theres nothing wrong with those functions.
(except i forgot to return a string in the edited code.)
(which is not the problem i am after.)

I think it's line 685

How do i make sure it's not searching beyond the bounds of the string before performing the test?

(every 4 characters represents a move. The fifth character will always be a space ' ' or "" unluess it is a pawn promotion in which case it will be 'e7e8Q' where it promotes to a white Queen and such.)

Fix

if (i+4 < imax) {
685. str = passd.substr(i + 4, 1);
if (str != " " && !str.empty()){
 
board[i2] = char2promote( passd.substr(i + 4, 1), onmove);
i++; // extra character in sequence.
}
}

in my VB6 equivalent i did this at the same point

If ch <> " " And ch <> Chr$(13) And ch <> "" Then
Dim x1  As Integer
x1 = brd(i2)

brd(i2) = char2promote(ch)
If brd(i2) = 0 Then brd(i2) = x1 Else i = i + 1
End If

thats different

i will compile with the fix and see
(the VB6 version works correctly)

just get the stack trace and get see what's the function calls it until
you find your code.Then check the parameter values.

uhhh heyy
i have two guesses right now its either substr(,) called too many times etc or wrong or the move list index

I'll check those and see

copythe following:

position startpos moves f2f4 d7d5 g1f3 b8c6 c2c3 f7f6 d2d3 e7e5 f4e5 f6e5 b1d2 g8f6 e2e4 f8c5 d2b3 c5b6 d1e2 e8g8 c1e3 d5d4 e3f2 f6g4 f2g3 d4c3 b2c3 g4e3 f3e5 c6e5 g3e5 c8g4 e2d2 d8e7 e5d4 b6d4 b3d4 e3f1 h1f1 f8f1 e1f1 a8f8 f1g1 e7g5 d2g5

paste it into the console app of mine
and hit enter.

It fails regardless of contents of the functions whitelist, blacklist

I tried changing fromSQ[180] toSQ[180] to fromSQ[250] toSQ[250]
and it didnt make a lick of difference.

so its not the bounds of the legal list of moves in whitelist or blacklist

its in

int main(void)

lol

I tried to compile using VC+ 2008 Express:

your program has a lot of unused variables that you need to clean up to prevent millions of warnings about it.

It also contains a couple real syntax errors. But you probably missed your compiler's error messages with all those warnings about unused variables.

line 556: what is setup ?

line 608: wnat is noplay ?

[edit]Ok noplay is a label. But you can get rid of it by removing the goto statement.

function checkblack() does not return a string. That could be a huge problem for anything calling that function.

Teh full source
http://www3.telus.net/public/deepglue/chsde2108.cpp
http://www3.telus.net/public/deepglue/chsde2108.cpp

copy the following:

position startpos moves f2f4 d7d5 g1f3 b8c6 c2c3 f7f6 d2d3 e7e5 f4e5 f6e5 b1d2 g8f6 e2e4 f8c5 d2b3 c5b6 d1e2 e8g8 c1e3 d5d4 e3f2 f6g4 f2g3 d4c3 b2c3 g4e3 f3e5 c6e5 g3e5 c8g4 e2d2 d8e7 e5d4 b6d4 b3d4 e3f1 h1f1 f8f1 e1f1 a8f8 f1g1 e7g5 d2g5

paste it into the console app of mine
and hit enter.

this is just one of the situations it does this theres many more..
that produce same error _STL

It fails regardless of contents of the functions whitelist, blacklist

I tried changing fromSQ[180] toSQ[180] to fromSQ[250] toSQ[250]
and it didnt make a lick of difference.

so its not the bounds of the legal list of moves in whitelist or blacklist

its in
int main(void)

any help would be appreciated


my gut feeling is if i use
passd[index]
instead of passd.substr(i+x,1)

it will work properly

I been stuck on this one 'bug' since december

       board[i2] = board[i1];
       // board[36]
       board[i1] = 0;
       if (board[i2] == -king) bkingsq = i2;
       if (board[i2] == king) wkingsq =i2;
       string str;
       str = passd[i + 4];
       if (str != " " && !str.empty()){

        board[i2] = char2promote( passd[i + 4], onmove);
        i++;        // extra character in sequence.
       }

       if (onmove == "w"){ onmove = "b"; }else {onmove = "w";}
    }

    string f;
    string g;
    string list;


int char2promote(char a, string b){
int out1;
 char aa;
 aa =  a;
switch (aa){
case 'q':
out1 = queen;
break;
case 'r':
out1 = rook;
break;
case 'b':
out1 = bishop;
break;
case 'n':
out1 = knight;
break;
}
if (b == "b") out1 *= -1;
return out1;
}

I just changed those two parts and it doesnt crash like it did b4 YAY!
I'm marking this as solved

for some reason it didnt like converting string to char and back lol

Edited 3 Years Ago by mike_2000_17: Fixed formatting

full code fixed

Attachments
#include<iostream>
#include<string>
#include<stdio>
#include<stdlib>
#include<limits>
#include<time>
//#ifndef true                  //compile for BC45 (no bool values in BC45, bool is internal for BCC55
//#   define true 1
//#   define false 0
//#else
//#   define MAX_LEN 75
//#endif

using namespace std;


const int horiz = 0;
const int verti = 1;
const int diagonal1 = 2;
const int diagonal2 = 3;

const int pawn = 100;
const int bishop = 305;
const int knight = 300;
const int rook = 500;
const int queen = 900;
const int king = 2000;

string gpins, gchecks;
int board[64];
int wkingsq, bkingsq;

bool wkside, wqside, bkside, bqside;

string onmove;



int putab(int a, int b)
{
  int i;
  i = a + b*8;
	return i;
}

int char2promote(char a, string b){
int out1;
 char aa;
 aa =  a;
switch (aa){
case 'q':
out1 = queen;
break;
case 'r':
out1 = rook;
break;
case 'b':
out1 = bishop;
break;
case 'n':
out1 = knight;
break;
}
if (b == "b") out1 *= -1;
return out1;
}


string chfile(int x){
  static string cho;
 switch(x){
 case 0:
 cho = "a";
 break;
 case 1:
 cho = "b";
 break;
 case 2:
 cho = "c";
 break;
 case 3:
 cho = "d";
 break;
 case 4:
 cho = "e";
 break;
 case 5:
 cho = "f";
 break;
 case 6:
 cho = "g";
 break;
 case 7:
 cho = "h";
 break;

 }
 return cho;
}



string chrank(int x){
  static string cho;
 switch(x){
 case 0:
 cho = "1";
 break;
 case 1:
 cho = "2";
 break;
 case 2:
 cho = "3";
 break;
 case 3:
 cho = "4";
 break;
 case 4:
 cho = "5";
 break;
 case 5:
 cho = "6";
 break;
 case 6:
 cho = "7";
 break;
 case 7:
 cho = "8";
 break;

 }
 return cho;
}


int bounds (int a, int b)
{
if ((a >= 0) && (a <= 7) && (b >= 0) && (b <= 7))
{
return true;
}
else
{
return false;
}
}

const startup[64] = { rook, knight, bishop, queen, king, bishop, knight, rook, pawn, pawn,pawn,pawn,pawn,pawn,pawn, pawn, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -pawn, -pawn, -pawn, -pawn, -pawn, -pawn, -pawn, -pawn, -rook, -knight, -bishop, -queen, -king, -bishop, -knight, -rook};

const ncenter[64]= {-20, 0, 0, 0, 0, 0, 0, -20,  0, 1, 1, 1, 1, 1, 1, 0,  0, 1, 2, 2 , 2, 2, 1, 0,    0, 1, 2, 2 , 2, 2, 1, 0,  0, 1, 2, 2 , 2, 2, 1, 0,  0, 1, 2, 2 , 2, 2, 1, 0,  0, 1, 1, 1, 1, 1, 1, 0, -20, 0, 0, 0, 0, 0, 0, -20   } ;

void setup (void);

 int geta(int a){
//get file 0 - 7
int i;
i = int(a % 8);
return i;
}

int getb(int a){
//get rank 0 - 7
int i;
i = int(a/8);
return i;
}

int str2num(string f1)
{

int aa, bb;
 switch (f1[0]){
 case 'a':
 aa = 0;
 break;
 case 'b':
 aa = 1;
 break;
 case 'c':
 aa = 2;
 break;
 case 'd':
 aa = 3;
 break;
 case 'e':
 aa = 4;
 break;
 case 'f':
 aa = 5;
 break;
 case 'g':
 aa = 6;
 break;
 case 'h':
 aa = 7;
 break;
 }

 switch (f1[1]){
 case '1':
 bb = 0;
 break;
 case '2':
 bb = 1;
 break;
 case '3':
 bb = 2;
 break;
 case '4':
 bb = 3;
 break;
 case '5':
 bb = 4;
 break;
 case '6':
 bb = 5;
 break;
 case '7':
 bb = 6;
 break;
 case '8':
 bb = 7;
 break;
 }

return aa + bb*8;

}

string coord2(int c){
 int a, b;
 static string e, f;
 

 a = geta(c);
 b = getb(c);
 e = chfile(a);
 f = chrank(b);
 e += f;

 return e;
 }
string checkblack(int, int);



int sgn(int h){
 if (h > 0) {return 1;}
 if (h < 0) {return -1;}
 return 0;
}






void setup (void) {
int i;
	for (i = 0; i < 64; i++){
	board[i] = startup[i]; //setup starting position
	}
  onmove = "w";
  
  wkside = true;
  wqside = true;
  bkside = true;
  bqside = true;

  wkingsq = 4;
  bkingsq = 60;
}



string checkblack(int ksq, int remv){
	int checklist[9];
	int a, b, c, d, e, f, g, num, x;
	num = 0;
	int repl;

	if (remv != 64) {

	repl = board[remv];
	board[remv] = 0;

	}

	static string freturn;
	a = geta(ksq);
	b = getb(ksq);



	for (e = -2; e < 3; e++){
	 for (f = -2; f < 3; f++){

		  if (abs(e) + abs(f) == 3)     //  check for black knight giving check
			{
			 c = a + e;
			 d = b + f;
			 if (bounds(c, d))
			 {
			 x = putab(c, d);
			  if (board[x] == knight )
				{
				checklist[num++] = x;
				}
			 }
			}               // end check for black knight
		  if ((abs(e) == 1 || abs(f) == 1) && abs(e) + abs(f) <= 2) //check for black king giving check
		  {
         c = a + e;
			 d = b + f;
			 if (bounds(c, d))
			 {
			 x = putab(c, d);
			  if (board[x] == king )
				{
				checklist[num++] = x;
				}
			 }
		  }    // end check for black king

		g = abs(e) + abs(f);
		if (g == 1)         	// check for queen and rook
		{
		c = a + e;
		d = b + f;
		 while (bounds(c, d))
		 {
			x = putab(c, d);
			if (board[x] == queen || board[x] == rook) {
			checklist[num] = x;
			num++;
		 }
			if (board[x] != 0) break;

			c = c + e;
			d = d + f;
		 }
		}


				 //bishop or queen
				 if (g == 2 && abs(e) == 1) {
					  c = a + e;
					  d = b + f;
					  while (bounds(c, d)) {
							x = putab(c, d);
							if (board[x] == queen || board[x] == bishop) {
								 checklist[num] = x;
								 num = num + 1;
							}
							if (board[x] != 0) break; // TODO: might not be correct. Was : Exit Do

							c = c + e;
							d = d + f;
					  }
				 }
	 }
	}

 //black pawns deliver check
	  c = a + 1;
	  d = b - 1;

	  if (bounds(c, d)) {
			x = putab(c, d);
			if (board[x] == pawn) {
				 checklist[num] = x;
				 num++;
			}
	  }

	  c = a - 1;
	  d = b - 1;
	  if (bounds(c, d)) {
			x = putab(c, d);
			if (board[x] == pawn) {
				 checklist[num] = x;
				 num++;
			}
	  }

	  string aa, bb, cc, dd;
switch (num)
{
case 0:
freturn.clear();
break;
case 1:
aa = chfile(geta(ksq));
bb = chrank(getb(ksq));
x = checklist[0];
cc = chfile(geta(x));
dd = chrank(getb(x));
freturn = aa + bb + cc + dd;
break;
default:
aa = chfile(geta(ksq));
bb = chrank(getb(ksq));
x = checklist[0];
cc = chfile(geta(x));
dd = chrank(getb(x));
freturn = aa + bb + cc + dd;
x = checklist[1];
cc = chfile(geta(x));
dd = chrank(getb(x));
freturn = freturn + cc + dd;
break;

}
if (remv != 64) {
board[remv] = repl;
}
 return freturn;
 }

string checkwhite(int ksq, int remv){
	int checklist[9];
	int a, b, c, d, e, f, g, num, x;
	int repl;
	num = 0;
	static string freturn;

	if (remv != 64) {

	repl = board[remv];
	board[remv] = 0;

	}
	a = geta(ksq);
	b = getb(ksq);



	for (e = -2; e < 3; e++){
	 for (f = -2; f < 3; f++){

		  if ((abs(e) + abs(f)) == 3)     //  check for black knight giving check
			{
			 c = a + e;
			 d = b + f;
			 if (bounds(c, d))
			 {
			 x = putab(c, d);
			  if (board[x] == -knight )
				{
				checklist[num++] = x;
				}
			 }
			}               // end check for black knight
		  if ((abs(e) == 1 || abs(f) == 1) && abs(e) + abs(f) <= 2) //check for black king giving check
		  {
         c = a + e;
			 d = b + f;
			 if (bounds(c, d))
			 {
			 x = putab(c, d);
			  if (board[x] == -king )
				{
				checklist[num++] = x;
				}
			 }
		  }    // end check for black king

		g = abs(e) + abs(f);
		if (g == 1)         	// check for queen and rook
		{
		c = a + e;
		d = b + f;
		 while (bounds(c, d))
		 {
			x = putab(c, d);
			if (board[x] == -queen || board[x] == -rook) {
			checklist[num] = x;
			num++;
		 }
			if (board[x] != 0) break;

			c = c + e;
			d = d + f;
		 }
		}


				 //bishop or queen
				 if (g == 2 && abs(e) == 1) {
					  c = a + e;
					  d = b + f;
					  while (bounds(c, d)) {
							x = putab(c, d);
							if (board[x] == -queen || board[x] == -bishop) {
								 checklist[num] = x;
								 num = num + 1;
							}
							if (board[x] != 0) break; // TODO: might not be correct. Was : Exit Do

							c = c + e;
							d = d + f;
					  }
				 }
	 }
	}

 //black pawns deliver check
	  c = a + 1;
	  d = b + 1;

	  if (bounds(c, d)) {
			x = putab(c, d);
			if (board[x] == -pawn) {
				 checklist[num] = x;
				 num++;
			}
	  }

	  c = a - 1;
	  d = b + 1;
	  if (bounds(c, d)) {
			x = putab(c, d);
			if (board[x] == -pawn) {
				 checklist[num] = x;
				 num++;
			}
	  }

	  string aa, bb, cc, dd;

switch (num)
{
case 0:
freturn.clear();
break;
case 1:

aa = chfile(geta(ksq));
bb = chrank(getb(ksq));
x = checklist[0];
cc = chfile(geta(x));
dd = chrank(getb(x));
freturn = aa + bb + cc + dd;

break;
default:
aa = chfile(geta(ksq));
bb = chrank(getb(ksq));
x = checklist[0];
cc = chfile(geta(x));
dd = chrank(getb(x));
freturn = aa + bb + cc + dd;
x = checklist[1];
cc = chfile(geta(x));
dd = chrank(getb(x));
freturn = freturn + cc +dd;
break;

}
if (remv != 64) {
board[remv] = repl;
}
 return freturn;
 }





int getplane(int c, int d){
if (c == 0 && d <= -1 ) { return verti;}
if (c <= -1 && d == 0 ) { return horiz;}
if (c >= 1 && d == 0 ) { return horiz;}
if (c >= 1 && d <= -1 ) { return diagonal1;}
if (c <= -1 && d <= -1 ) { return diagonal2;}
if (c == 0 && d >= 1 ) { return verti;}
if (c <= -1 && d >= 1 ) { return diagonal1;}
if (c >= 1 && d >= 1 ) { return diagonal2;}
return 0;
}

int comparePlane(int square1, int square2)  {
int a, b, c, d, e, f, g, x, y;
a = geta(square1);
b = getb(square1);
c = geta(square2);
d = getb(square2);
x = a - c;
e = sgn(x);
y = b - d;
f = sgn(y);
g = getplane(e, f);
return g;
}


string whitepin(int ksq) {
	  int pinner[8];
	  int pinned[8];

	  int foundpiece, piecepinned;

	  if (ksq == 64) return "";

	  int numpins = 0;
	  int a, b, c, d, e, f, g, h, x;

	  a = geta(ksq);
	  b = getb(ksq);

	  for (e = -1; e <= 1; e++) {
			for (f = -1; f <= 1; f++) {

				 g = abs(e);
				 h = abs(f);

				 //bishop pin
				 if (g + h == 2) {
					  c = a + e;
					  d = b + f;
					  foundpiece = false;
					  while (bounds(c, d)) {
							x = putab(c, d);
							if (board[x] > 0) {
							if (foundpiece == false) {
									  piecepinned = x;
									  foundpiece = true;
								 }
								 else {
                             break; // TODO: might not be correct. Was : Exit Do
								 }
							}
							if ((board[x] < 0 && board[x] != -bishop && board[x] != -queen)) break; // TODO: might not be correct. Was : Exit Do

							if ((board[x] == -bishop || board[x] == -queen) && foundpiece == true) {
								 pinner[numpins] = x;
								 pinned[numpins] = piecepinned;
								 numpins++;
								 break; // TODO: might not be correct. Was : Exit Do
							}

							c = c + e;
							d = d + f;
					  }
				 }

				 //rook/queen pin
				 if (g + h == 1) {

					  c = a + e;
					  d = b + f;
					 // debg = num2
This question has already been answered. Start a new discussion instead.