Exemplo n.º 1
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;
	}
}
Exemplo n.º 2
0
Arquivo: unadf.c Projeto: NF6X/ADFlib
int main(int argc, char* argv[])
{
    int i, j;
    BOOL rflag, lflag, xflag, cflag, vflag, sflag, dflag, pflag, qflag;
    struct List* files, *rtfiles;
    char *devname, *dirname;
    char strbuf[80];
    unsigned char *extbuf;
    int vInd, dInd, fInd, aInd;
    BOOL nextArg;

    struct Device *dev;
    struct Volume *vol;
    struct List *list, *cell;
    int volNum;
    BOOL true = TRUE;

    if (argc<2) {
        help();
        exit(0);
    }

    rflag = lflag = cflag = vflag = sflag = dflag = pflag = qflag = FALSE;
    vInd = dInd = fInd = aInd = -1;
    xflag = TRUE;
    dirname = NULL;
    devname = NULL;
    files = rtfiles = NULL;
    volNum = 0;

    fprintf(stderr,"unADF v%s : a unzip like for .ADF files, powered by ADFlib (v%s - %s)\n\n",
        UNADF_VERSION, adfGetVersionNumber(),adfGetVersionDate());

    /* parse options */
    i=1;
    while(i<argc) {
        if (argv[i][0]=='-') {
            j=1;
            nextArg = FALSE;
            while(j<(int)strlen(argv[i]) && !nextArg) {
                switch(argv[i][j]) {
                case 'v':
                    vflag = TRUE;
                    if ((i+1)<(argc-1)) {
                        i++;
                        nextArg = TRUE;
                        errno = 0;
                        volNum = atoi(argv[i]);
                        if (errno!=0 || volNum<0) {
                            fprintf(stderr,"invalid volume number, aborting.\n");
                            exit(1);
                        }
                    }
                    else
                        fprintf(stderr,"no volume number, -v option ignored.\n");
                    break;
                case 'l': 
                    lflag = TRUE;
                    xflag = FALSE;
                    break;
                case 's': 
                    sflag = TRUE;
                    break;
                case 'c': 
                    cflag = TRUE;
                    break;
                case 'r':
                    rflag = TRUE;
                    break;
                case 'd':
                    if (devname!=NULL && xflag && (i+1)==(argc-1)) {
                        i++;
                        dirname = argv[i];
                        if (dirname[strlen(dirname)-1]==DIRSEP)
                            dirname[strlen(dirname)-1]='\0';
                        nextArg = TRUE;
                        dflag = TRUE;
                    }
                    break;
                case 'p':
                    if (xflag) {
                        fprintf(stderr,"sending files to pipe.\n");
                        pflag = TRUE;
                        qflag = TRUE;
                    }
                    else
                        fprintf(stderr,"-p option must be used with extraction, ignored.\n");
                    break;
                case 'h':
                default:
                    help();
                    exit(0);
                } /* switch */
            j++;
            } /* while */
        } /* if */
        else {
			/* the last non option string is taken as a filename */
            if (devname==NULL) /* if the device name has been already given */
                devname = argv[i];
            else {
                if (xflag) {
                    if (rtfiles==NULL)
                        rtfiles = files = newCell(NULL, (void*)argv[i]);
                    else
                        files = newCell(files, (void*)argv[i]);
                }
                else
                    fprintf(stderr,"Must be used with extraction, ignored.\n");
            }
        }
        i++;
    } /* while */

    extbuf =(unsigned char*)malloc(EXTBUFL*sizeof(char));
    if (!extbuf) { fprintf(stderr,"malloc error\n"); exit(1); }

    /* initialize the library */
    adfEnvInitDefault();

    dev = adfMountDev( devname,TRUE );
    if (!dev) {
        sprintf(strbuf,"Can't mount the dump device '%s'.\n", devname);
        fprintf(stderr, strbuf);
        adfEnvCleanUp(); exit(1);
    }
    if (!qflag)
        printDev(dev);

    if (volNum>=dev->nVol) {
        fprintf(stderr,"This device has only %d volume(s), aborting.\n",dev->nVol);
        exit(1);
    }

    vol = adfMount(dev, volNum, TRUE);
    if (!vol) {
        adfUnMountDev(dev);
        fprintf(stderr, "Can't mount the volume\n");
        adfEnvCleanUp(); exit(1);
    }

    if (!qflag) {
        printVol(vol, volNum);
        putchar('\n');
    }

    if (cflag && isDIRCACHE(vol->dosType) && lflag) {
        adfChgEnvProp(PR_USEDIRC,&true);
        if (!qflag)
            puts("Using dir cache blocks.");
    }

    if (lflag) {
        if (!rflag) {
            cell = list = adfGetDirEnt(vol,vol->curDirPtr);
            while(cell) {
                printEnt(vol,cell->content,"", sflag);
                cell = cell->next;
            }
            adfFreeDirList(list);
        } else {
            cell = list = adfGetRDirEnt(vol,vol->curDirPtr,TRUE);
            printTree(vol,cell,"", sflag);
            adfFreeDirList(list);
        }
    }else if (xflag) {
        if (rtfiles!=NULL) {
            files = rtfiles;
            while(files!=NULL) {
                if (dirname!=NULL)
                    processFile(vol, (char*)files->content, dirname, extbuf, pflag, qflag);
                else
                    processFile(vol, (char*)files->content, "", extbuf, pflag, qflag);
                files = files->next;
            }
            freeList(rtfiles);
        }
        else {
            cell = list = adfGetRDirEnt(vol,vol->curDirPtr,TRUE);
            if (dirname==NULL)
                extractTree(vol, cell, "", extbuf, pflag, qflag);
            else
                extractTree(vol, cell, dirname, extbuf, pflag, qflag);
            adfFreeDirList(list);
        }
    }
    else
        help();

    free(extbuf);

    adfUnMount(vol);
    adfUnMountDev(dev);

    adfEnvCleanUp();

    return(0);
}
Exemplo n.º 3
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;
	}
}