// **************************************************************************** // * * // * Velena Source Code V1.0 * // * Written by Giuliano Bertoletti * // * Based on the knowledged approach of Louis Victor Allis * // * Copyright (C) 1996-97 by Giuliano Bertoletti & GBE 32241 Software PR * // * * // **************************************************************************** // Portable engine version. // read the README file for further informations. // ========================================================================== // This module contains the main function. Just see file cmdline.c to see how // to send positions to the engine. // Main module #include #include #include #include #include #include "connect4.h" #include "pnsearch.h" #include "proto.h" #define WHITEBOOK_MEM (0x800B0000) #define WHITEBOOK_SIZE 846986 #define BLKSIZE 16384 // Buffer size for I/O #define PLAYER1 0 #define PLAYER2 1 struct board *brd; short check_solution_groups(struct board *board) { short x,y,z,q,c,answer=YES; for(y=0;ysolvable_groups->sqpnt[ELM(x,y)] && answer;z++) { answer=NO; c=board->solvable_groups->square[ELM(x,y)][z]; for(q=0;qgroups[c][q]==ELM(x,y)) answer=YES; } return answer; } // Initialize the program data structures, it reads and builds (if needed) // the opening book. void init_prg(struct board *board) { long size,len; short x; brd=board; board->wins[PLAYER1]=0; board->wins[PLAYER2]=0; board->draws =0; board->lastguess =0; board->bestguess =MAXMEN; board->lastwin =EMPTY; board->white_lev=0; // Human board->black_lev=3; // Computer-Strong board->videotype = CHARS; board->enablegr = NO; board->autotest = NO; for(x=0;x<3;x++) board->rule[x]=0L; board->oracle_guesses=0; size=WHITEBOOK_SIZE; if(size%14!=0) fatal_error("White opening book is corrupted"); board->wbposit=size/14; board->white_book=WHITEBOOK_MEM; board->bbposit=0; } void initboard(struct board *board) { short x,y,i,j,p; randomize(); for(i=0;i<10;i++) board->instances[i]=0L; /* Groups initializations */ // Step one. Horizontal lines. i=0; for(y=0;ygroups[i][0]=&board->square[ELM(x+0,y)]; board->groups[i][1]=&board->square[ELM(x+1,y)]; board->groups[i][2]=&board->square[ELM(x+2,y)]; board->groups[i][3]=&board->square[ELM(x+3,y)]; board->xplace[i][0]=x; board->xplace[i][1]=x+1; board->xplace[i][2]=x+2; board->xplace[i][3]=x+3; board->yplace[i][0]=y; board->yplace[i][1]=y; board->yplace[i][2]=y; board->yplace[i][3]=y; i++; } // Step two. Vertical lines for(y=0;ygroups[i][0]=&board->square[ELM(x,y+0)]; board->groups[i][1]=&board->square[ELM(x,y+1)]; board->groups[i][2]=&board->square[ELM(x,y+2)]; board->groups[i][3]=&board->square[ELM(x,y+3)]; board->xplace[i][0]=x; board->xplace[i][1]=x; board->xplace[i][2]=x; board->xplace[i][3]=x; board->yplace[i][0]=y+0; board->yplace[i][1]=y+1; board->yplace[i][2]=y+2; board->yplace[i][3]=y+3; i++; } // Step three. Diagonal (north east) lines for(y=0;ygroups[i][0]=&board->square[ELM(x+0,y+0)]; board->groups[i][1]=&board->square[ELM(x+1,y+1)]; board->groups[i][2]=&board->square[ELM(x+2,y+2)]; board->groups[i][3]=&board->square[ELM(x+3,y+3)]; board->xplace[i][0]=x+0; board->xplace[i][1]=x+1; board->xplace[i][2]=x+2; board->xplace[i][3]=x+3; board->yplace[i][0]=y+0; board->yplace[i][1]=y+1; board->yplace[i][2]=y+2; board->yplace[i][3]=y+3; i++; } // Step four. Diagonal (south east) lines for(y=3;ygroups[i][0]=&board->square[ELM(x+0,y-0)]; board->groups[i][1]=&board->square[ELM(x+1,y-1)]; board->groups[i][2]=&board->square[ELM(x+2,y-2)]; board->groups[i][3]=&board->square[ELM(x+3,y-3)]; board->xplace[i][0]=x+0; board->xplace[i][1]=x+1; board->xplace[i][2]=x+2; board->xplace[i][3]=x+3; board->yplace[i][0]=y-0; board->yplace[i][1]=y-1; board->yplace[i][2]=y-2; board->yplace[i][3]=y-3; i++; } for(x=0;x<64;x++) { board->solvable_groups->sqpnt[x]=0; for(y=0;y<16;y++) board->solvable_groups->square[x][y]=-1; } for(x=0;xsquare[ELM(x,y)]=ELM(x,y); for(i=0;igroups[i][j]; board->solvable_groups->square[p][board->solvable_groups->sqpnt[p]++]=i; } // Here we set all out squares to a default value to detect problems for(i=0;i<8;i++) { board->square[ELM(7,i)]=FULL; board->square[ELM(i,6)]=board->square[ELM(i,7)]=FULL; } board->stack[7]=FULL; for(y=0;ysquare[ELM(x,y)]=EMPTY; for(x=0;xstack[x]=0; board->turn=WHITE; board->filled=0; board->cpu=0x01; return; } void initTitle() { printf("\n"); printf("Velena Engine %s; revision %s\n",SEARCH_ENGINE_VERSION,__DATE__); printf("\n"); printf("Connect four AI engine written by Giuliano Bertoletti\n"); printf("Based on the knowledged approach of Victor Allis\n"); printf("Copyright (C) 1996-97 Giuliano Bertoletti "); printf("and GBE 32241 Software PR.\n"); printf("All rights reserved.\n\n"); } struct board *the_board; void setup_veleng(void) { short x; // Here we initialize our environment and the call // command_line_input in file cmdline.c to process data from the // outside world. initTitle(); fight(NO); brd=NULL; the_board=(struct board *)c4_malloc(sizeof(struct board)); the_board->solvable_groups=(struct solvable_groups *) c4_malloc(sizeof(struct solvable_groups)); if(!the_board || !the_board->solvable_groups) fatal_error("Cannot allocate memory!"); the_board->debug=0; init_prg(the_board); // Initialize data structures for(x=0;xsolution[x]=(struct solution *) c4_malloc(sizeof(struct solution)); if(!the_board->solution[x]) fatal_error("Not enough memory for solutions"); } the_board->usegraphics = NO; } void close_veleng (void) { int x; for(x=0;xsolution[x]) free(the_board->solution[x]); free(the_board->solvable_groups); free(the_board); }