TicTac field[NSIZE_I*NSIZE_J];
the structures themselves may be typedef enum {Tic, Tac, EMPTY} TicTac;
, the game will need a lot of procedures (relatively of course), the code validation procedure implemented as int validstep(const TicTac *field, int step){ return ((field[step]==EMPTY)&&((step + NSIZE_J >= NSIZE_I*NSIZE_J)||((step + NSIZE_J < NSIZE_I*NSIZE_J)&&(field[step + NSIZE_J] != EMPTY))));}
, the generator of moves was performed in the simplest and non-optimal way, but the least brainwashing - by simply looking at the equations of verticals, horizontals and diagonals, it turned out quite voluminous, but nothing complicated int c4getrait(const TicTac *field, TicTac Me){ int i, j, k, score=0, maxscore=-1; /* X X X */ for(i=0; i<NSIZE_I; i++){ score=0; for(j=0; j<NSIZE_J; j++){ //printf( "i=%d; j=%d\n", i, j ); if(field[i*NSIZE_J + j] == Me) score++; else { maxscore = (score > maxscore)?score:maxscore; score = 0; if(maxscore == WIN) return maxscore; } } maxscore = (score > maxscore)?score:maxscore; } /* XXX */ for(j=0; j<NSIZE_J; j++){ score=0; for(i=0; i<NSIZE_I; i++){ if(field[i*NSIZE_J + j] == Me) score++; else { maxscore = (score > maxscore)?score:maxscore; score = 0; if(maxscore == WIN) return maxscore; } } maxscore = (score > maxscore)?score:maxscore; } /*main up diag XXX XX X */ for(k=0; k<NSIZE_J; k++){ score=0; for(i=0, j=NSIZE_J-k-1; i<NSIZE_I&&j>=0; i++, j--){ //printf( "i=%d; j=%d\n", i, j ); if(field[i*NSIZE_J + j] == Me) score++; else { maxscore = (score > maxscore)?score:maxscore; score = 0; if(maxscore == WIN) return maxscore; } } //printf( "\n" ); maxscore = (score > maxscore)?score:maxscore; }...
. Step game(TicTac *field, int deep, WHO it, TicTac t){ int i=0; float rait, koeff = 1 - Koeff[it]*deep; Step s, r; s.step = -1; s.rait = -1000.; if(deep > DEEPMAX){ s.rait = 0.; return s; } for(i=0; i<NSIZE_I*NSIZE_J; i++){ if( validstep(field, i) ){ field[i] = t; rait = c4getrait(field, t); if(rait >= WIN){ field[i] = EMPTY; s.rait = 10.*koeff; s.step = i; return s; } else if(!isstep(field)){ rait = 0.; } else { r = game(field, deep+1, it, (t==Tic)?Tac:Tic); rait-=r.rait; } if(rait > s.rait){ s.rait = rait; s.step = i; } field[i] = EMPTY; } } s.rait = s.rait*koeff; return s; }
The procedure iterates through all positions in the cycle. for(i=0; i<NSIZE_I*NSIZE_J; i++){...
make another move field[i] = t;
looking for evaluation rait = c4getrait(field, t);
if we won if(rait >= WIN){
, it makes no sense to look deeper - no, the recursion stops, if there are no moves (a draw) - we return 0 (maybe not optimal), otherwise r = game(field, deep+1, it, (t==Tic)?Tac:Tic); rait-=r.rait;
we estimate the opponent's reaction to our move and calculate the rating, then we select the maximum rating and return the position if(rait > s.rait){ s.rait = rait; s.step = i; } field[i] = EMPTY;
, return the result s.rait = s.rait*koeff; return s;
.Source: https://habr.com/ru/post/224653/
All Articles