URL
https://opencores.org/ocsvn/connect-6/connect-6/trunk
Subversion Repositories connect-6
Compare Revisions
- This comparison shows the changes necessary to convert path
/connect-6/trunk
- from Rev 12 to Rev 13
- ↔ Reverse comparison
Rev 12 → Rev 13
/BUILD_SCC/synth_src/search_bfs.cpp
30,23 → 30,24
int maxi(int x,int y){ |
return (x>=y)?x:y; |
} |
static AIWEIGHT df_search(Board *b, AIMoves *moves,unsigned int *index, Player *player, |
static AIWEIGHT df_search(Board *b, AIMoves *moves,index_array *index, Player *player, |
int depth, int cache_index, |
PIECE searched, AIWEIGHT alpha, AIWEIGHT beta) |
/* Depth is in _moves_ */ |
{ |
#pragma bitsize index 9 |
#pragma internal_fast index |
unsigned int index1[361]={0}; |
#pragma bitsize index 9 |
#pragma internal_fast index |
int i, j; |
#pragma bitsize i 16 |
#pragma bitsize j 16 |
Board b_next[5][16]; |
#pragma internal_blockram b_next |
AIMoves moves_next[5][16]; |
#pragma internal_fast moves_next |
AIWEIGHT utility[5][16]; |
int branch=player->branch; |
|
board_copy(b, &b_next[0][0]); |
ai_threats(b_next,0,0,moves_next,index); |
|
|
///* Search only the top moves beyond the minimum */ |
60,18 → 61,11
//} |
|
/* No moves left -- its a draw */ |
for(i=0;i<branch;i++){ |
moves_next[0][0].data[i].x=moves->data[i].x; |
moves_next[0][0].data[i].y=moves->data[i].y; |
moves_next[0][0].data[i].weight=moves->data[i].weight; |
} |
moves_next[0][0].utility=moves->utility; |
moves_next[0][0].len=branch; |
|
if (moves->len < 1) //"(%s)", bcoords_to_string(aim->x, aim->y)); |
if (moves_next[0][0].len < 1) //"(%s)", bcoords_to_string(aim->x, aim->y)); |
|
return AIW_DRAW; |
board_copy(b, &b_next[0][0]); |
//board_copy(b, &b_next[0][0]); |
|
/* Search each move available in depth first order */ |
for(j=0;j<depth;j++){ |
80,17 → 74,22
//int branches=(player->branch)^j; |
//printf("branches %d\n",branches); |
for (i = 0; i < branches; i++) { |
AIMove *aim = moves_next[j][i>>1].data + (i % branch); |
//if(!(moves_next[j][i>>1].utility==AIW_WIN || moves_next[j][i>>1].utility==-AIW_WIN)){ |
if(!(utility[j][i>>1]==AIW_WIN || utility[j][i>>1]==-AIW_WIN)){ |
AIMove aim = *(moves_next[j][i>>1].data + (i % branch)); |
//printf ("aim->utility %d \n",moves_next[j][i>>1].utility); |
|
board_copy(&b_next[j][i>>1], &b_next[j+1][i]); |
//if(moves_next[j][i/2].len<branch) printf ("caca"); |
//printf("%d %d\n",aim.x,aim.y); |
|
/* Did we get a bad move? */ |
//if (!piece_empty(piece_at(&b_next[j+1][i], aim->x, aim->y))) { |
// //g_warning("DFS utility function suggested a bad move " |
// //"(%s)", bcoords_to_string(aim->x, aim->y)); |
// //printf("bad move\n"); |
// continue; |
//} |
if (!piece_empty(piece_at(&b_next[j+1][i], aim.x, aim.y))) { |
//g_warning("DFS utility function suggested a bad move " |
//"(%s)", bcoords_to_string(aim->x, aim->y)); |
//printf("bad move\n"); |
continue; |
} |
|
/* Already searched here? */ |
///////////////////////////if (piece_at(&b_next[j+1][i], aim->x, aim->y) == searched){ |
100,7 → 99,7
///////////////////////////place_piece_type(&b_next[j+1][i], aim->x, aim->y, searched); |
|
//b_next = board_new(); |
place_piece(&b_next[j+1][i], aim->x, aim->y); |
place_piece(&b_next[j+1][i], aim.x, aim.y); |
AIWEIGHT next_alpha = alpha, next_beta = beta; |
//AIFunc func; |
|
117,12 → 116,15
|
/* Did we win? */ |
|
if (check_win_full(&b_next[j+1][i], aim->x, aim->y,0,0,0,0)){ |
aim->weight = AIW_WIN; |
if (check_win_full(&b_next[j+1][i], aim.x, aim.y,0,0,0,0)){ |
aim.weight = AIW_WIN; |
moves_next[j+1][i].utility=AIW_WIN; |
utility[j+1][i]=AIW_WIN; |
|
|
}else if(moves_next[j][i>>1].utility==AIW_WIN || moves_next[j][i>>1].utility==-AIW_WIN ){ |
moves_next[j+1][i].utility=AIW_WIN; |
//moves_next[j+1][i].utility=AIW_WIN; |
utility[j+1][i]=AIW_WIN; |
/* Otherwise, search deeper */ |
}else { |
|
132,7 → 134,8
// return moves->utility; |
//} |
//moves_next = func(b_next); |
ai_threats(&b_next[j+1][i],&moves_next[j+1][i],&index1[0]); |
ai_threats(b_next,j+1,i,moves_next,index); |
utility[j+1][i]=moves_next[j+1][i].utility; |
|
//aim->weight = df_search(&b_next, &moves_next, index,player, |
// depth - 1, next_ci, searched, |
140,7 → 143,8
//aimoves_free(moves_next); |
} |
if (b_next[j+1][i].turn != b->turn) |
moves_next[j+1][i].utility=-moves_next[j+1][i].utility; |
//moves_next[j+1][i].utility=-moves_next[j+1][i].utility; |
utility[j+1][i]=-moves_next[j+1][i].utility; |
//if (moves_next[j+1][i].utility >= AIW_WIN) |
// moves_next[j+1][i].utility=AIW_WIN; |
|
155,19 → 159,21
//} |
|
//board_free(b_next); |
if (aim->weight > alpha) { |
alpha = aim->weight; |
//cache_set(cache_index, aim); |
//if (aim->weight > alpha) { |
// alpha = aim->weight; |
// //cache_set(cache_index, aim); |
|
/* Victory abort */ |
if (alpha >= AIW_WIN) |
return AIW_WIN; |
// /* Victory abort */ |
// if (alpha >= AIW_WIN) |
// return AIW_WIN; |
|
/* Alpha-beta pruning */ |
if (alpha >= beta) |
return alpha; |
} |
// /* Alpha-beta pruning */ |
// if (alpha >= beta) |
// return alpha; |
//} |
//printf("%d %d %d\n",j,i,moves_next[j+1][i].utility); |
}else //moves_next[j+1][i].utility=AIW_WIN; |
utility[j+1][i]=AIW_WIN; |
} |
} |
for(j=depth-1;j>0;j--){ |
177,27 → 183,42
//printf("branches %d player %d\n",branches,b_next[j+1][i].turn); |
for (i = 0; i < branches; i=i+2) { |
if (b_next[j+1][i].turn != b->turn) |
moves_next[j][i>>1].utility=maxi(moves_next[j+1][i].utility,moves_next[j+1][i+1].utility); |
//moves_next[j][i>>1].utility=mini(moves_next[j+1][i].utility,moves_next[j+1][i+1].utility); |
utility[j][i>>1]=mini(utility[j+1][i],utility[j+1][i+1]); |
else |
moves_next[j][i>>1].utility=mini(moves_next[j+1][i].utility,moves_next[j+1][i+1].utility); |
//moves_next[j][i>>1].utility=maxi(moves_next[j+1][i].utility,moves_next[j+1][i+1].utility); |
utility[j][i>>1]=maxi(utility[j+1][i],utility[j+1][i+1]); |
|
//printf("%d %d\n",moves_next[j+1][i].utility,moves_next[j+1][i+1].utility); |
} |
} |
|
//for(i=0;i<branch;i++){ |
//moves_next[0][0].data[i].x=moves->data[i].x; |
//moves_next[0][0].data[i].y=moves->data[i].y; |
//moves_next[0][0].data[i].weight=moves->data[i].weight; |
//} |
//moves_next[0][0].utility=moves->utility; |
//moves_next[0][0].len=branch; |
for(i=0;i<branch;i++){ |
moves->data[i].weight=moves_next[1][i].utility; |
moves->data[i].x=moves_next[0][0].data[i].x; |
moves->data[i].y=moves_next[0][0].data[i].y; |
//moves->data[i].weight=moves_next[1][i].utility; |
moves->data[i].weight=utility[1][i]; |
} |
moves->len=branch; |
|
return alpha; |
} |
|
int search(const Board *b, AIMove *move, Player *player) |
int search(Board *b, AIMove *move, Player *player) |
{ |
AIMoves moves; |
#pragma internal_blockram moves |
moves.len=0; |
Board copy; |
#pragma internal_blockram copy |
unsigned int index[361]={0}; |
#pragma bitsize index 9 |
index_array index={0}; |
#pragma internal_fast index |
//AIFunc move_func = ai(player->ai)->func; |
|
251,14 → 272,14
//cache_best = AIW_MIN; |
//copy = board_new(); |
board_copy(b, ©); |
ai_threats(©,&moves,&index[0]); |
//ai_threats(©,&moves,&index); |
|
//if (player->search == SEARCH_DFS) { |
df_search(©, &moves, &index[0],player, player->depth, 0, |
df_search(©, &moves, &index,player, player->depth, 0, |
PIECE_SEARCHED, AIW_LOSE, AIW_WIN); |
//printf("%d %d \n",moves.data[0].weight,moves.data[1].weight); |
int ret_val; |
ret_val=aimoves_choose(&moves, move,&index[0]); |
ret_val=aimoves_choose(&moves, move,&index); |
if (!ret_val) |
return 0; |
else return 1; |
/BUILD_SCC/synth_src/threats.cpp
348,7 → 348,7
#pragma fifo_length pico_stream_output_queue 800 |
#pragma bandwidth pico_stream_input_queue 1 |
#pragma bandwidth pico_stream_output_queue 1 |
/*AIMoves*/int ai_threats(Board *board,AIMoves *moves,unsigned int *index) |
/*AIMoves*/int ai_threats(Board board[5][16],int depth,int branch,AIMoves moves[5][16],index_array *index) |
{ |
//#pragma read_write_ports board.data combined 2 |
//#pragma internal_blockram board |
356,7 → 356,6
|
//#pragma internal_blockram move |
//#pragma no_memory_analysis move |
#pragma bitsize index 9 |
#pragma internal_fast index |
|
/////////* All threat functions work on this board */ |
376,7 → 375,7
//#pragma internal_blockram moves |
//#pragma no_memory_analysis moves |
|
moves->len=0; |
moves[depth][branch].len=0; |
//AIMoves moves; |
AIWEIGHT u_sum = 0; |
int i; |
383,7 → 382,7
|
//b = board_new(); |
//Board b; |
board_copy(board, &b); |
board_copy(&board[depth][branch], &b); |
|
/* Clear threat tallys */ |
//for (i = 0; i < connect_k; i++) { |
533,9 → 532,9
#pragma internal_blockram moves1 |
/*moves = */ ai_marks(&bwrite, PIECE_THREAT(1),&moves1); |
//test(ready); |
streamsort(moves,index); |
streamsort(&moves[depth][branch],index); |
moves1.utility = u_sum; |
moves->utility = u_sum; |
moves[depth][branch].utility = u_sum; |
/*---------------------------- |
rewritten for hardware |
----------------------------*/ |
687,7 → 686,7
// } |
|
} |
void streamsort(AIMoves *moves,unsigned int *index){ |
void streamsort(AIMoves *moves,index_array *index){ |
/* Insertion sort for streaming*/ |
AIMove val; |
AIMove data[361]={{-1},{-1},{-1}}; |
737,7 → 736,7
break; |
} |
} |
index[i]=len; |
index->data[i]=len; |
moves->data[i]=val; |
len++; |
//cout<<"STREAMSORT"<<":"; |
803,13 → 802,13
//#pragma internal_blockram moves |
//#pragma no_memory_analysis moves |
//AIMove move; |
unsigned int index[1]={0}; |
index_array index={0}; |
//AIMoves *moves; |
moves.len=0; |
/* Get all open tiles adjacent to any piece */ |
/*moves =*/ enum_adjacent(b, 1,&moves,current_random); |
if (moves.len){ |
aimoves_choose(&moves, move,&index[0]); |
aimoves_choose(&moves, move,&index); |
|
return ;//moves; |
} |
/BUILD_SCC/synth_src/shared.h
144,7 → 144,7
/* These threat markers are usable by the AIs */ |
}; |
typedef int PIECE; |
//#pragma bitsize PIECE 16 |
#pragma bitsize PIECE 32 |
|
#define MAX_THREAT (INT_MAX - PIECE_THREAT0) |
/* Highest value a threat marker can have */ |
189,6 → 189,10
} Board; |
/* The board structure represents the state of the game board. Do NOT preserve |
board pointers across games. */ |
typedef struct{ |
unsigned int data[361]; |
#pragma bitsize data 9 |
} index_array; |
|
extern AllocChain *board_root; |
extern gsize board_mem; |
344,7 → 348,7
///////////* Add an AIMove to an AIMoves array; existing moves weights will be |
////////// overwritten */ |
////////// |
int aimoves_choose(AIMoves *moves, AIMove *move, unsigned int *index); |
int aimoves_choose(AIMoves *moves, AIMove *move, index_array *index); |
/* Will choose one of the best moves from a GArray of AIMove structures at |
random. Returns non-zero if a move was chosen or zero if a move could not |
be chosen for some reason. */ |
419,7 → 423,7
/*AIMoves **/ void enum_adjacent(Board *b, int dist,AIMoves *moves,unsigned int current_random); |
/* Enumerate empty tiles at most dist away from some other piece on the board */ |
|
void streamsort(AIMoves *moves,unsigned int *index); |
void streamsort(AIMoves *moves,index_array *index); |
/*AIMoves **/void ai_marks(Board *b, PIECE min,AIMoves *moves); |
/* Fills a moves list with tiles marked at least PIECE_THREAT(min) */ |
|
459,7 → 463,7
///////////AIMoves *ai_dfs_utility(const Board *b); |
////////////* Utility function */ |
/////////// |
/*AIMoves **/int ai_threats(Board *board,AIMoves *moves,unsigned int *index); |
/*AIMoves **/int ai_threats(Board board[5][16],int depth,int branch,AIMoves moves[5][16],index_array *index); |
AIMoves *ai_priority(const Board *b); |
/* Multi-level threats */ |
|
483,5 → 487,5
//SEARCH search; |
int depth, branch, cache, tss; |
} Player; |
/*AIMoves **/int search(const Board *board,AIMove *move, Player *player); |
/*AIMoves **/int search(Board *board,AIMove *move, Player *player); |
#endif |
/BUILD_SCC/synth_src/connect6.cpp
206,7 → 206,7
highx = x; |
highy = y; |
currenthigh = temp; |
highRandom =1;// rand(); |
highRandom =1;//rand(); |
} |
// If a tie happens, pseudo-randomly choose one between them |
if (temp == currenthigh && temp != 0){ |
/BUILD_SCC/synth_src/state.cpp
213,7 → 213,7
return ((AIMove*)b)->weight - ((AIMove*)a)->weight; |
} |
|
int aimoves_choose(AIMoves *moves, AIMove *move,unsigned int *index) |
int aimoves_choose(AIMoves *moves, AIMove *move,index_array *index) |
{ |
//#pragma read_write_ports moves.data combined 3 |
//#pragma internal_blockram moves |
/BUILD_SCC/synth_src/main.cpp
219,7 → 219,7
connect6ai(board,AI_colour,move); |
movecount++; |
cout<<"AI MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl; |
if(movecount >=20) return 0 ; //reducing length of simulation |
//if(movecount >=20) return 0 ; //reducing length of simulation |
winning_colour = check_for_win(board); |
if (winning_colour == AI_colour){ |
cout<<"AI has won! " << movecount << " moves " << "Exiting."<<endl; |
/BUILD_SCC/synth_src/main.cpp.base
219,7 → 219,7
connect6ai(board,AI_colour,move); |
movecount++; |
cout<<"AI MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl; |
if(movecount >=20) return 0 ; //reducing length of simulation |
//if(movecount >=20) return 0 ; //reducing length of simulation |
winning_colour = check_for_win(board); |
if (winning_colour == AI_colour){ |
cout<<"AI has won! " << movecount << " moves " << "Exiting."<<endl; |