Example #1
0
//Board Methods defined 
void Board::updateBoard() //updates the board display after pieces have been drawn
{
	chessboard.display(main_disp);//update board
	debugbox.display(debug_disp);

	if(turn == true) //was blacks turn, checks for check
	{
		if(isCheck(pieceArray[30]->getX(), pieceArray[30]->getY(), -2, -2, -2, -2))
		{
			check = true;
			debugbox.fill(0).draw_text(0,0, "CHECK!", green);
		}
		
	}
	else if(turn == false) //was whites turn, checks for check
	{
		if(isCheck(pieceArray[31]->getX(), pieceArray[31]->getY(), -2, -2, -2, -2))
		{
			check = true;
			debugbox.fill(0).draw_text(0,0, "CHECK!", green);
		}
	}
}
Example #2
0
int main()
{
	int *op;
	int j,i;
	for(i=0;i<10;i++)
	{
		op=productArray(testDB[i].input,testDB[i].length);
		if(isCheck(op,i))
			printf("valid\n");
		else
			printf("Invalid\n");
		free(op);
	}
	return 0;
}
Example #3
0
bool PathArithmetic::findValidGrid(Vec2 from,Vec2 to,vector<Vector<Grid*>> _gridArray){
	PointDelegate* fromDelegate = PointDelegate::create(from.x,from.y);
	invalidPoints.pushBack(fromDelegate);
	Vector<PointDelegate*> points;
	//先添加原点周围八个点
	points.pushBack(PointDelegate::create(from.x,from.y-1));
	points.pushBack(PointDelegate::create(from.x,from.y+1));
	points.pushBack(PointDelegate::create(from.x-1,from.y));
	points.pushBack(PointDelegate::create(from.x+1,from.y));
	points.pushBack(PointDelegate::create(from.x-1,from.y-1));
	points.pushBack(PointDelegate::create(from.x+1,from.y+1));
	points.pushBack(PointDelegate::create(from.x-1,from.y+1));
	points.pushBack(PointDelegate::create(from.x+1,from.y-1));
	//使用临时vector集合
	Vector<PointDelegate*> temp;
	for(int i = 0; i<points.size();i++){
		PointDelegate* pd = points.at(i);
		Vec2 p = Vec2(pd->getX(),pd->getY());
		if(p.equals(to)){
			pathPoints.pushBack(pd);
			return true;
		}
		//检查点的有效性,即是否是障碍物
		if(isCheck(p,_gridArray)){
			temp.pushBack(pd);
		}
	}


	std::sort(temp.begin(),temp.end(),
		[=](const Ref* obj1,const Ref* obj2){
			PointDelegate* p1 = (PointDelegate*)obj1;
			PointDelegate* p2 = (PointDelegate*)obj2;
			double r1 = sqrt((p1->getX() - to.x) * (p1->getX() - to.x) + (p1->getY() - to.y) * (p1->getY() - to.y));
			double r2 = sqrt((p2->getX() - to.x) * (p2->getX() - to.x) + (p2->getY() - to.y) * (p2->getY() - to.y));
			return r1 < r2 ? -1 : 0;  //负数为从小到大
	});
	for(int i = 0; i < temp.size();i++){ //
		PointDelegate* pd = temp.at(i);
		Vec2 p = Vec2(pd->getX(),pd->getY());
		bool flag = findValidGrid(p,to,_gridArray);
		if(flag){
			pathPoints.pushBack(pd);
			return true;
		}
	}
	return false;
}
Example #4
0
GameStatus Model::checkGameStatus(int player) const {

    MOVES avMoves;
    bool check;
    avMoves = allMoves(player);
    check = isCheck(player);

    if (avMoves.size() == 0 && check == true) {
        return MATE;
    } else if (avMoves.size() == 0) {
        return STALEMATE;
    } else if (check == true) {
        return CHECK;
    }
    return USUAL;
}
Example #5
0
	void	FalagardCheckButton::drawSelf(float z)
	{
		if( d_needsRedraw )
		{
			if( isCheck() && !isPushed())
			{
				d_renderCache.clearCachedImagery();
            // signal that we'll no loger need a redraw.
				d_needsRedraw = false;
				drawPushed( z );
			}
			else
				return FalagardButton::drawSelf( z );
		}
		Window::drawSelf(z);
	}
Example #6
0
/**
* Gibt 1 zurueck, wenn ein Zug ausgefuehrt wurde, sonst 0.
*/
char aiDeepMove(struct GameState *gameState) {
	char from 			= 0;
	char to 			= 0;
	char coordFrom[]	= "??";
	char coordTo[]		= "??";
	int eval 			= 0;
	int bestEvalAdding 	= 0;

	if (loadOpeningBookMove(gameState, coordFrom, coordTo)) {
		from = convertCoordToIndex(coordFrom);
		to = convertCoordToIndex(coordTo);
		printf("Eroeffnungsbuch: ");
	} else {
		timeStamp = time(NULL);
		aiDeepSearch(gameState, &from, &to, &eval, &bestEvalAdding, 0);
		if (debugMode) printDev("Calculation time: %i\n", (int) time(NULL) - timeStamp);
	}

	if (from != 0) {
		convertIndexToCoord(from, coordFrom); 
		convertIndexToCoord(to, coordTo);

		if ((*gameState).board[to] == 0) {
			printInfo("KI zieht mit %c von %s nach %s.\n", getPieceSymbolAsChar((*gameState).board[from]), coordFrom, coordTo);	
		} else {
			printInfo("KI zieht mit %c von %s nach %s und schlaegt %c.\n", getPieceSymbolAsChar((*gameState).board[from]), coordFrom, coordTo, getPieceSymbolAsChar((*gameState).board[to]));	
		}
		
		doMovePartial(gameState, from, to);
		doMoveFinal(gameState, from, to);

		return 1;
	} else {
		printf("Blah 3!\n"); exit(1);
		if (eval <= -valueCheckMate) {
			if (isCheck(gameState)) {
				printInfo("KI ist Schachmatt!\n");		
			} else {
				printInfo("KI gibt auf: Schachmatt in wenigen Zuegen!\n");	
			}
		} else {
			printError("Fehler: Keine Zuege gefunden, aber nicht Schachmatt!"); // DEBUG
		}
		
		return 0;
	}
}
Example #7
0
int main ( int argc ,char * argv[] ) {

	int t , n;
	scanf("%d" , &n);

	for (  t = 1 ; t <= n ; t++ ) {
		int r,c;
		readChess(&r,&c);

		int a = isCheck(r,c);

		if ( a == 1 ) {
			printf("Case #%d: Check\n" , t);
		}
		else {
			printf("Case #%d: Not Check\n" , t);
		}
	}

	return 0;
}
Example #8
0
/**
* Fuehrt einen Move durch (falls moeglich).
* Der GameState wird als Referenz uebergeben. from und to sind Board Indizes.
* Gibt 1 zurueck, wenn der Zug durchgefuhert werden konnte, sonst 0.
*/
char doUserMove(struct GameState *gs, char from, char to) {
	char player = (*gs).turnNumber % 2;
	if (isCurrentPlayerOwner(gs, from)) { // er muss eine Figur auf dem Startfeld besitzen
		if (isCurrentPlayerOwner(gs, to) == 0) { // aber auf dem Zielfeld darf er keine Figur besitzen
			char moves[28];
			generatePieceMoves(gs, from, moves);

			for (char i = 0; i < 28; i++) {
				if (moves[i] == 0) break;
				if (moves[i] == to) { // Zug durchfuehren:
					short pieceFrom = (*gs).board[from];
					short pieceTo = (*gs).board[to];

					doMovePartial(gs, from, to);

					char checkPiece = isCheck(gs);
					if (checkPiece) { // Schach?
						(*gs).board[from] = pieceFrom;
						(*gs).board[to] = pieceTo;
						printError("Zug nicht moeglich - der eigene Koenig kaeme unter Schach durch gegnerischen %c!\n", getPieceSymbolAsChar(checkPiece));
						return 0;
					} else {
						doMoveFinal(gs, from, to);
					}
					
					break;
				}
			}
			return 1;
		} else {
			printError("Der Spieler %i besitzt eine Figur auf dem Zielfeld!\n", player);
			return 0;	
		}
	} else {
		printError("Der Spieler %i besitzt keine Figur auf dem Ausgangsfeld!\n", player);
		return 0;
	}
}
Example #9
0
bool Board::move(move_t move) {
	// add to move history stack
	Piece captured_piece;
	if (move.bits & 1) {
		captured_piece = pieces[move.to];
	} else {
		captured_piece = _;
	}
	hist_t hist = {move, captured_piece, side_castle, xside_castle, ep};
	move_history.push(hist);

	// make move
	color[move.from] = EMPTY;
	color[move.to] = side;
	pieces[move.to] = pieces[move.from];
	pieces[move.from] = _;

	// move rook if castling
	if (move.bits & 2) {
		if (side == WHITE) {
			if (move.to == 62) { // kingside
				color[63] = EMPTY;
				color[61] = side;
				pieces[63] = _;
				pieces[61] = R;
			} else { // queenside
				color[56] = EMPTY;
				color[59] = side;
				pieces[56] = _;
				pieces[59] = R;
			}
		} else {
			if (move.to == 57) { // kingside
				color[56] = EMPTY;
				color[58] = side;
				pieces[56] = _;
				pieces[58] = R;
			} else { // queenside
				color[63] = EMPTY;
				color[60] = side;
				pieces[63] = _;
				pieces[60] = R;
			}
		}
		side_castle = 0;
	}

	// update castling rights
	if (pieces[56] != R || color[56] != side) side_castle &= (side ? 2 : 1);
	if (pieces[63] != R || color[63] != side) side_castle &= (side ? 1 : 2);
	if (side == WHITE && (pieces[60] != K || color[60] != side)) side_castle = 0;
	if (side == BLACK && (pieces[59] != K || color[59] != side)) side_castle = 0;

	if (pieces[0] != R || color[0] != xside) xside_castle &= (side ? 1 : 2);
	if (pieces[7] != R || color[7] != xside) xside_castle &= (side ? 2 : 1);
	if (xside == WHITE && (pieces[3] != K || color[3] != xside)) xside_castle = 0;
	if (xside == BLACK && (pieces[4] != K || color[4] != xside)) xside_castle = 0;

	// promotion
	if (move.bits & 4) {
		pieces[move.to] = move.promote;
	}

	// en passant captures the pawn
	if (move.bits & 8) {
		color[move.to + 8] = EMPTY;
		pieces[move.to + 8] = _;
	}

	// moving pawn 2 squares forwards sets up en passant
	if (move.bits & 16) {
		ep = 63 - (move.from - 8);
	} else {
		ep = -1;
	}

	Board::rotateBoard();
	std::swap(side, xside);
	std::swap(side_castle, xside_castle);

	if (isCheck(xside)) {
		undoMove();
		return false;
	}

	return true;
}
Example #10
0
int scoreBest(char* board,int player){
	linkedList *moves = getMoves(board, BLACK);
	if (moves->first == NULL){ // no possible moves for other player
		if (isCheck(board, BLACK)){ // check
			freeList(moves);
			return 2*kingScore; // the player wins
		}
		else // not in check
		{
			freeList(moves);
			return -0; // tie
		}
	}
	freeList(moves);
	moves = getMoves(board, WHITE);
	if (moves->first == NULL){ // no possible moves
		if (isCheck(board, WHITE)){ // check
			freeList(moves);
			return -2 * kingScore; // the player lost
		}
		else // not in check
		{
			freeList(moves);
			return -0; // tie
		}
	}
	freeList(moves);
	int score = 0;
	pos p;
	for (char x = 'a'; x <= 'h'; x++)
	{
		p.x = x;
		for (int y = 1; y <= 8; y++)
		{
			p.y = y;
			int ind = posToInd(p);
			char type = tolower(board[ind]);
			if (type == EMPTY)
			{
				continue;
			}
			int color = colorOfLoc(board, ind);
			int ind64 = color == WHITE ? posToBoard64(p) : 64 - posToBoard64(p);
			if (type == 'm')
			{
				score += pawnScore * (2 * color - 1);
				score += pawnTable[ind64];
			}
			else if (type == 'n'){
				score += knightScore * (2 * color - 1);
				score += knightTable[ind64];
			}
			else if (type == 'b'){
				score += bishopScore * (2 * color - 1);
				score += bishoptTable[ind64];
			}
			else if (type == 'r'){
				score += rookScore * (2 * color - 1);
				score += rookTable[ind64];
			}
			else if (type == 'q'){
				score += queenScore * (2 * color - 1);
				score += queenTable[ind64];
			}
		}
	}
	return score * (2 * player - 1);
}
Example #11
0
/** Returns if the black player (isTestForBlackPlayer-true) or white player (isTestForBlackPlayer=false)
*	are in tie (their king is not in danger but no additional moves can be made).
*	To optimize, this method accepts possibleMoves for the given player, to avoid calculating them all over again.
*/
bool isTie(char board[BOARD_SIZE][BOARD_SIZE], bool isTestForBlackPlayer, LinkedList* possibleMoves)
{
	return ((possibleMoves->length == 0) && (!isCheck(board, isTestForBlackPlayer)));
}
Example #12
0
bool Board::validMove(int srcX, int srcY, int destx, int desty) //determines if move is valid
{
		bool collisionLegal = false;
		bool typeMoveLegal = false;
		bool sameTeam = true;

		int idPiece = boardarray[srcX][srcY];
		int srcPiece = idPiece;
		if(srcPiece >= 0 && srcPiece <= 15) //special condition for pawn transformations
		{
			if(pieceArray[srcPiece]->getPawnTrans())
			{
				srcPiece = pieceArray[idPiece]->getPieceRule();
			}

		}
		
		int destPiece = boardarray[destx][desty]; //neccessary variables
		int srcPieceColor = 0;
		int destPieceColor = 0;
		bool whiteColorsrc = pieceArray[srcPiece]->getWhite();
		bool whiteColorDest = false;
		bool checkMove = true;
		int colorTurn = 0;

		if(turn)  //sets piece color, true is white
			colorTurn = 1;
		else
			colorTurn = 2;

		if(whiteColorsrc) srcPieceColor = 1; 
			else srcPieceColor = 2;

		if(colorTurn == srcPieceColor){					//checks for whose turn it is

			
			if(destPiece != -1){						//fixes OutofIndex error
				whiteColorDest = pieceArray[destPiece]->getWhite();

				if(whiteColorDest) destPieceColor = 1;		//checks for friendly fire
				else destPieceColor = 2;
			}
			else destPieceColor = 3;

			if(srcPieceColor == destPieceColor)
				sameTeam = false;
			
			typeMoveLegal = pieceArray[srcPiece]->moveLegal(destx, desty, srcX, srcY, destPiece); 
			collisionLegal = collision(destx, desty, srcX, srcY);		

			
			if(srcPiece == 31 || srcPiece == 30) //special instance for castling
				castling(&typeMoveLegal, srcX, srcY, destx, desty, srcPiece);

		
			if(typeMoveLegal && collisionLegal && turn) //legal move, white turn, checks if king is in check
			{
				if(isCheck(pieceArray[WHITEKING]->getX(), pieceArray[WHITEKING]->getY(), destx, desty, srcX, srcY))
				{
					checkMove = false;
				}
				else
					check = false;
			}
			else if(typeMoveLegal && collisionLegal && !turn) //legal move, black turn, checks if king is in check
			{
				if(isCheck(pieceArray[BLACKKING]->getX(), pieceArray[BLACKKING]->getY(), destx, desty, srcX, srcY))
				{
					checkMove = false;//sets valid move to false if king is still hypothetically in check, preventing your move from happening
				}
				else
					check = false;
			}	

	
			//EN PASSANT
			if((srcPiece >= 0 && srcPiece <= 15))
			//if((srcPiece >= 0 || srcPiece <= 17) && collisionLegal && sameTeam && checkMove)
			{
				enPassant(&typeMoveLegal, srcX, srcY, destx, desty, srcPiece, whiteColorsrc, srcPieceColor);
			}

			if(srcPiece >= 20 && srcPiece <= 23)
				collisionLegal = true;
	
			if(typeMoveLegal && collisionLegal && sameTeam && checkMove)//everything is true - valid move
			{
				if(srcPiece >= 0 && srcPiece <= 15){			//checks if that pawn is moved to other side
					if(whiteColorsrc && desty == 0){			//for white peices
						pieceArray[srcPiece]->setTransform();
					}
					if(!whiteColorsrc && desty == 7){			//for black pieces
						pieceArray[srcPiece]->setTransform();
					}
				}

				if(idPiece == 30 || idPiece == 31 || (idPiece <= 27 && idPiece >= 24) || (idPiece >= 0 && idPiece <= 15))
					pieceArray[srcPiece]->setFirstMoved();	
				moveCount++;
				turn = !turn;
				return true;
			}
		}

		return false; //false if move not valid
	
		
}
Example #13
0
/**
* Ermittelt den besten Zug aus der uebergebenen Stellung.
*
* from = Poistionsindex des Start des Zugs, to = Ziel
* bestEval = die beste ermittelte Bewertung
* bestEvalAdding = zusätzliche Bewertung die genutzt werden kann, um gleichbewertete Zuege zu priorisieren
* depth = die aktuelle Zugtiefe
*/
void aiDeepSearch(struct GameState *gameState, char *from, char *to, int *bestEval, int *bestEvalAdding, char depth) {
	short movesCounter;
	char moves[28 * 16 * 2]; // keine Initialiserung!
	struct GameState gs;

	if (depth == 0 && autoMode) printBoard((*gameState).board, 0, 0);

	// Erzeuge lokale Kopie des GameState der beliebig veraendert werden kann:
	copyGameState(gameState, &gs); 

	// Erzeuge Zuege:
	generateMoves(&gs, moves, &movesCounter);

	// Zunaechst alle Zuege auf Gueltigkeit (Schach) untersuchen.
	// Ungueltige Zuege aussortieren.
	short move;
	short found = 0; // gefundene gueltige Zuege
	int eval = 0;
	int evalAdding = 0;
	*bestEval = -valueCheckMate; // valueCheckMate bedeutet: Der bewertende Spieler ist Schachmatt/Patt
	//*bestEvalAdding = 0;
	for (move = 0; move < movesCounter; move += 2) {
		short pieceFrom = gs.board[moves[move]];
		short pieceTo = gs.board[moves[move + 1]];

		// Testzug machen:
		//printDev("Betrachte Zug %i  von %i (%i) nach %i (%i).\n", move, moves[move], pieceFrom, moves[move+1], pieceTo);
		doMovePartial(&gs, moves[move], moves[move + 1]);

		if (isCheck(&gs)) { // Eigener Koenig unter Schach?
			//printDev("Ausortierter Zug %i von %i nach %i da Schachgebot von: %i\n", move, moves[move], moves[move+1], isCheck(&gs));
			// derzeit: nichts tun
		} else {
			found++;

			if (depth >= maxDepth) {
				eval = evaluateBoard(gs.board);
				evalAdding = 0;
				if (gs.turnNumber % 2 == 1) eval *= -1; // ist der Spieler, der am Zug ist, schwarz, die Bewertung umdrehen (da sie immer aus Sicht von Weiss erfolgt)
				//printDev("Betrachte Zug %i von %i nach %i. Bewertung: %i\n", move, moves[move], moves[move+1], eval);
			} else {
				gs.turnNumber++; // Zugnummer erhoehen damit der naechste Spieler am Zug ist
				char rfrom = 0; // der Wert wird nicht benoetigt
				char rto = 0;
				aiDeepSearch(&gs, &rfrom, &rto, &eval, &evalAdding, depth + 1);		

				eval *= -1; // NegaMax-Algorithmus: Die Bewertung umdrehen. Aus der Sicht des Spielers, der in dieser Funktion gerade berechnet wird, ist der andere Spieler der Gegner und ein gutes Ergebnis von ihm fuer ihn selber schlecht.
				evalAdding *= -1;
				gs.turnNumber--;

				if (debugMode && depth == 0) {
					if (pieceTo == 0) {
						printDev("[%3.0f%%] Deep Search: Zug mit %c von %i nach %i. Bewertung: %6i\n", ((double) move / (double) movesCounter) * 100, getPieceSymbolAsChar(pieceFrom), moves[move], moves[move+1], eval);
					} else {
						printDev("[%3.0f%%] Deep Search: Zug mit %c von %i nach %i und schlaegt %c. Bewertung: %6i\n", ((double) move / (double) movesCounter) * 100, getPieceSymbolAsChar(pieceFrom), moves[move], moves[move+1], getPieceSymbolAsChar(pieceTo), eval);
					}
				}
			}

			// Schlagzuege unterhalb der tiefsten Ebene (Evaluationsebene) werden minimal vorteilhaft bewertet.
			// Der Grund dafuer ist, dass es sonst zu Situationen kommen kann, in denen die KI zwar schlagen kann,
			// was auch vorteilhat waere im Sinne der Bewertung, es aber nicht tut.
			// Warum nicht? Weil in diesen Situationen die KI sieht, dass die eine Figur sicher schlagen kann, und zwar
			// innerhalb ihres ganzen Horizonts. Es ist dann aus Sicht der KI egal, ob sie die Figur diese oder naechste Runde schlaegt.
			// Aber es kann sein, dass die KI die Situation in der naechsten Runde wiede so bewertet und das Schlagen
			// immer auf einen zukuenftigen Zeitpunkt verschiebt. Deshalb wird das schlagen minimal positiv bewertet.
			if (pieceTo != 0) evalAdding += pow(2, maxDepth + 1 - depth);

			if (eval > *bestEval || (eval == *bestEval && evalAdding > *bestEvalAdding)) {
				if (debugMode && depth == 0) printDev("Dieser Zug hat nun die beste Bewertung.\n");
				*bestEval = eval;
				*bestEvalAdding = evalAdding;
				*from = moves[move];
				*to = moves[move + 1];
			}
		}

		// Zug rueckgaengig machen:
		gs.board[moves[move]] = pieceFrom;
		gs.board[moves[move + 1]] = pieceTo;

		//if (eval > valueCheckMate) {
		//	printDev("Checkmate-Cutoff!\n");
		//	break;
		//} 
	}

	// Wenn ich keine gueltigen Zuege habe, bin ich schachmatt oder patt.
	// Daher auf Schach pruefen: Besteht kein Schach, dann bin ich patt.
	// In diesem Fall gebe ich anstatt -valueCheckMate (=Schachmatt) als Bewertung 0 zurueck.
	// Damit weiss der Spieler, der vor mir am Zug ist, zwar nicht genau, dass es ein Patt ist.
	// Das ist aber irrelevant.
	if (found == 0) {
		if (isCheck(&gs) == 0) *bestEval = 0;
	}
}
Example #14
0
/**
* Hauptmethode
*/
int main(int argc, char *argv[]) {
	hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
	char o;
	char boardMode = 0; // 0/1
	char fullScreen = 1;
	char from[] = "??";
	char to[] = "??";
	char filename[255];
	char moves[28 * 16 * 2]; // keine Initialiserung!
	short movesCounter = 0;
	short board[120];
	int eval;
	int okay;
	int i;

	struct GameState gameState;
	struct GameState gameStateCopy;
	createStartBoard(board);
	setGameState(&gameState, board, 0, 3, 4);

	srand((unsigned int) time(NULL));  // Zufallsgenerator initialisieren

	if (fullScreen) system("cls");

	do {
		printf("\nSpieler: %i, Halbzug: %i\n", gameState.turnNumber % 2, gameState.turnNumber);
		printBoard(gameState.board, 0, boardMode);

		COLOR(128);
		printf("\n> Kommando:");
		COLOR(COLOR_DEFAULT);
		printf(" ");
        scanf("%c", &o); // Auf Char scannen
        fflush(stdin);

        if (fullScreen && o != 'm') system("cls");

        switch (o) {
        	case 'x':
        		// "magic" move - alles ist moeglich. Auch, Fehler zu produzieren.
        	case 'm':
        		printf("Zug von: ");
        		scanf("%s", from);
        		fflush(stdin);

        		printf("Zug nach: ");
        		scanf("%s", to);
        		fflush(stdin);

        		if (strlen(from) != 2 || strlen(to) != 2) {
        			printError("Ungueltige Koordinaten!\n");
        		} else {
        			autoSave(&gameState);
        			if (o == 'x') {
						doMovePartial(&gameState, convertCoordToIndex(from), convertCoordToIndex(to));
						doMoveFinal(&gameState, convertCoordToIndex(from), convertCoordToIndex(to));
        			} else {
        				if (doUserMove(&gameState, convertCoordToIndex(from), convertCoordToIndex(to))) system("cls");
        			}
        		}
        		break;
        	case 'n':
        		gameState.turnNumber--;
				printInfo("Zug zurueck.\n");
        		break;
        	case 'a':
        		do {
        			autoSave(&gameState);
        			okay = aiMove(&gameState, 0);
        		} while (autoMode && okay && ((gameState.turnNumber % 2 == 0 && gameState.ai0) || (gameState.turnNumber % 2 == 1 && gameState.ai1)));
        		break;
        	case 'c':
        		printInfo("Schach: %i\n", isCheck(&gameState));
        		break;
        	case 'h':
        		printHistory();
        		break;
        	case 'g':
        		generateMoves(&gameState, moves, &movesCounter);
        		printInfo("%i moegliche Zuege (ohne Beruecksichtigung von Schach).\n", movesCounter / 2);
				for (i = 0; i < movesCounter; i += 2) {
					printf("Zug mit %i von %i nach %i.\n", gameState.board[moves[i]], moves[i], moves[i + 1]);
				}
        		break;
        	case 'v':
        		eval = evaluateBoard(gameState.board);
        		printInfo("Evaluation (aus Sicht von weiss): %i\n", eval);
        		break;
        	case 't':
        		copyGameState(&gameState, &gameStateCopy);
    			okay = aiMove(&gameStateCopy, 3);
        		break;
        	case 'o':
        		okay = loadOpeningBookMove(&gameState, from, to);
        		if (okay) {
        			printInfo("Zugvorschlag aus dem Eroeffnungsbuch: mit %c von %s nach %s", getPieceSymbolAsChar(gameState.board[convertCoordToIndex(from)]), from, to);
        		} else {
        			printInfo("Das Eroeffnungsbuch enthaelt keinen passenden Zug!");
        		}
        		break;
        	case 's':
        		saveGame(&gameState, "quicksave", 1);
        		break;
        	case 'r':
				loadGame(&gameState, "quicksave");
        		break;
        	case 'l':
        		system("dir savegames\\*.sav /B");
				printf("\nLade Datei (Endung nicht angeben):\n");
				scanf("%s", filename);
				fflush(stdin);

				loadGame(&gameState, filename);
        		break;
        	case 'u':
        		loadAutoSave(&gameState);
        		break;
        	case 'b':
        		boardMode = (1 - boardMode);
        		printInfo("Brettdarstellung gewechselt auf: %i\n", boardMode);
        		break;
        	case 'd':
        		debugMode = (1 - debugMode);
        		printInfo("Debugmodus gewechselt auf: %i\n", debugMode);
        		break;
        	case '?':
        		printf("m (move)\tEinen Zug durchfuehren.\n");
        		printf("n (next)\tDen Spieler wechseln (ohne Zug, regelwidrig!)\n");
        		printf("a (ai)\t\tKI einen Zug durchfuehren lassen.\n");
        		printf("h (history)\tDen Spielverlauf anzeigen.\n");
        		printf("c (check)\tStellung auf Schach pruefen.\n");
        		printf("g (generate)\tMoegliche Zuege anzeigen lassen.\n");
        		printf("v (value)\tBewertung der Stellung anzeigen lassen.\n");
        		printf("t (tip)\t\tDie KI einen Zug-Tip anzeigen lassen.\n");
        		printf("s (save)\tQuicksave-Spielstand anlegen.\n");
        		printf("r (reload)\tQuicksave-Spielstand laden.\n");
        		printf("l (load)\tSpielstand laden (Dateiname angeben).\n");
        		printf("u (undo)\tLetzten Zug zuruecknehmen.\n");
        		printf("b (board)\tBrettdarstellung wechseln (fuer Debuggging).\n");
        		printf("d (open)\tDebugausgaben aktivieren/deaktivieren.\n");
        		printf("? (help)\tDiese Hilfe zu den Kommandos anzeigen lassen.\n");
        		printf("e (exit)\tDas Programm beenden.\n");
        		break;
        	case 'e':
        		// do nothing
        		break;
        	case '\n':
        		// do nothing
        		break;
        	default:
        		printError("Unbekannter Operator: %c\n", o);
        		break;
        }
        fflush(stdin);
	} while (o != 'e');

	return 0;
}