OpenCores
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 4 to Rev 5
    Reverse comparison

Rev 4 → Rev 5

/DEMO/connect6 Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
DEMO/connect6 Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: DEMO/DE2.sof =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: DEMO/DE2.sof =================================================================== --- DEMO/DE2.sof (nonexistent) +++ DEMO/DE2.sof (revision 5)
DEMO/DE2.sof Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: DEMO/connectk =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: DEMO/connectk =================================================================== --- DEMO/connectk (nonexistent) +++ DEMO/connectk (revision 5)
DEMO/connectk Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: CONNECT6_CMDLINE/connect6.cpp =================================================================== --- CONNECT6_CMDLINE/connect6.cpp (nonexistent) +++ CONNECT6_CMDLINE/connect6.cpp (revision 5) @@ -0,0 +1,458 @@ +/* + connect6.cpp + June 9, 2011 + This file contains the game AI + By Kevin Nam + +*/ + +#include +#include + +#include "util.h" +#include "connect6.h" + +// Subtract this many points for moves at the edges. +#define EDGEPENALTY 5 + +using namespace std; + +/* The cost function simply counts all of the consecutive stones of same colour in + every direction from the spot for which the points is being calculated. + + Ex: + + .DDLL + .DLDD + DXDDD + ...D. + + Above, X is the spot being calculated. + The points would be 2 (above) + 2(topright) + 3(right) + 1 (left) = 8. + It treats opponent's stones and own stones with equal weighting. + + Return 0 if the spot y,x is already taken, else return the calculated value + +*/ +int calculatepoints(char board[][19], int y, int x, char colour){ + int pts = 0, tempx = x, tempy = y, tcount = 0,bcount = 0; + int lcount = 0,rcount = 0,trcount = 0,tlcount = 0,brcount = 0,blcount = 0; + char tcolour = 0,bcolour = 0,lcolour = 0,rcolour = 0,tlcolour = 0,trcolour = 0,brcolour = 0,blcolour = 0; + + if (board[y][x] != 0) + return 0; + + // scan column above + if (y > 0){ + tempy = y-1; + tempx = x; + tcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != tcolour || board[tempy][tempx] == 0) break; + tcount++; + if (tempy == 0) break; + tempy--; + } + } + // scan column below + if (y < 18){ + tempy = y+1; + tempx = x; + bcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != bcolour || board[tempy][tempx] == 0) break; + bcount++; + if (tempy == 18) break; + tempy++; + } + } + // scan row to left + if (x > 0){ + tempy = y; + tempx = x-1; + lcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != lcolour || board[tempy][tempx] == 0) break; + lcount++; + if (tempx == 0) break; + tempx--; + } + } + // scan row to right + if (x < 18){ + tempy = y; + tempx = x+1; + rcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != rcolour || board[tempy][tempx] == 0) break; + rcount++; + if (tempx == 18) break; + tempx++; + } + } + // scan diagonal topleft + if (x > 0 && y > 0){ + tempy = y-1; + tempx = x-1; + tlcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != tlcolour || board[tempy][tempx] == 0) break; + tlcount++; + if (tempx == 0 || tempy == 0) break; + tempx--; + tempy--; + } + } + // scan diagonal bottomright + if (x < 18 && y < 18){ + tempy = y+1; + tempx = x+1; + brcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != brcolour || board[tempy][tempx] == 0) break; + brcount++; + if (tempx == 18 || tempy == 18) break; + tempx++; + tempy++; + } + } + // scan diagonal topright + if (x < 18 && y > 0){ + tempy = y-1; + tempx = x+1; + trcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != trcolour || board[tempy][tempx] == 0) break; + trcount++; + if (tempx == 18 || tempy == 0) break; + tempx++; + tempy--; + } + } + // scan diagonal bottomleft + if (y < 18 && x > 0){ + tempy = y+1; + tempx = x-1; + blcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != blcolour || board[tempy][tempx] == 0) break; + blcount++; + if (tempy == 18 || tempx == 0) break; + tempy++; + tempx--; + } + } + + /// Now calculate the points + // Check if this is a winning move. Priority #1. + if ((tcount >= 5 && tcolour == colour) || + (bcount >= 5 && bcolour == colour) || + (lcount >= 5 && lcolour == colour) || + (rcount >= 5 && rcolour == colour) || + (tlcount >= 5 && tlcolour == colour) || + (trcount >= 5 && trcolour == colour) || + (brcount >= 5 && brcolour == colour) || + (blcount >= 5 && blcolour == colour) || + (tcount + bcount >= 5 && tcolour == colour && bcolour == colour) || + (lcount + rcount >= 5 && lcolour == colour && rcolour == colour) || + (tlcount + brcount >= 5 && tlcolour == colour && brcolour == colour) || + (trcount + blcount >= 5 && trcolour == colour && blcolour == colour)) + return 1000; + + // Check if this move can stop opponent from winning. This move is priority #2. + if ((tcount >= 4 && tcolour != colour) || + (bcount >= 4 && bcolour != colour) || + (lcount >= 4 && lcolour != colour) || + (rcount >= 4 && rcolour != colour) || + (tlcount >= 4 && tlcolour != colour) || + (trcount >= 4 && trcolour != colour) || + (brcount >= 4 && brcolour != colour) || + (blcount >= 4 && blcolour != colour) || + (tcount + bcount >= 4 && tcolour != colour && bcolour != colour) || + (lcount + rcount >= 4 && lcolour != colour && rcolour != colour) || + (tlcount + brcount >= 4 && tlcolour != colour && brcolour != colour) || + (trcount + blcount >= 4 && trcolour != colour && blcolour != colour)) + return 500; + + // Else sum up the counts, use this as the points. + pts = tcount + bcount + lcount + rcount + tlcount + trcount + blcount + brcount + 1; + // If at an edge, lower the points + if (x == 0 || x == 18 || y == 0 || y == 18){ + if (pts >= EDGEPENALTY) + pts -= EDGEPENALTY; + else + pts = 0; + } + return pts; +} + +/* + The AI Function that calls the cost function for every spot on the board. + It returns the location with the highest points. In the event of a tie, randomly decide. + Input the board and the colour being played. + Puts the move (in ASCII chars) inside move[4]. This is from [1 ... 19] + Puts the move (in integers) in moveY and moveX. This is from [0 ... 18] +*/ +int connect6ai(char board[][19], char colour, char move[4]){ + int x,y,highx = 0, highy = 0,currenthigh = 0, temp; + srand(time(NULL)); + int highRandom = rand(); + // Sweep the entire board with the cost function + for (x = 0; x <= 18; x++){ + for (y = 0; y <= 18; y++){ + + temp = calculatepoints(board,y,x, colour); + if (temp > currenthigh){ + highx = x; + highy = y; + currenthigh = temp; + highRandom = rand(); + } + // If a tie happens, pseudo-randomly choose one between them + if (temp == currenthigh && temp != 0){ + int tempRandom = rand(); + if (tempRandom > highRandom){ + highx = x; + highy = y; + highRandom = tempRandom; + } + } + } + } + + // Modify the board based on current move. + board[highy][highx] = colour; + + // Increment by 1 because indexing starts at 1. + highy++; + highx++; + + /// Convert the int coordinates to corresponding ASCII chars + if (highy >= 10){ + move[0] = '1'; + highy -= 10; + } else { + move[0] = '0'; + } + if (highy == 0) move[1] = '0'; + else if (highy == 1) move[1] = '1'; + else if (highy == 2) move[1] = '2'; + else if (highy == 3) move[1] = '3'; + else if (highy == 4) move[1] = '4'; + else if (highy == 5) move[1] = '5'; + else if (highy == 6) move[1] = '6'; + else if (highy == 7) move[1] = '7'; + else if (highy == 8) move[1] = '8'; + else if (highy == 9) move[1] = '9'; + + // Do same for x. + if (highx >= 10){ + move[2] = '1'; + highx -= 10; + } else { + move[2] = '0'; + } + if (highx == 0) move[3] = '0'; + else if (highx == 1) move[3] = '1'; + else if (highx == 2) move[3] = '2'; + else if (highx == 3) move[3] = '3'; + else if (highx == 4) move[3] = '4'; + else if (highx == 5) move[3] = '5'; + else if (highx == 6) move[3] = '6'; + else if (highx == 7) move[3] = '7'; + else if (highx == 8) move[3] = '8'; + else if (highx == 9) move[3] = '9'; + + return 0; +} + + +// scan board, return 'L' or 'D' for the winner, 'n' if no winner. +char check_for_win (char board[][19]){ + int y,x; + for (y = 0; y < 19; y++){ + for (x = 0; x < 19; x++){ + if (board[y][x] == 0) + continue; + + int tempx, tempy, tcount = 0,bcount = 0; + int lcount = 0,rcount = 0,trcount = 0,tlcount = 0,brcount = 0,blcount = 0; + char tcolour = 0,bcolour = 0,lcolour = 0,rcolour = 0,tlcolour = 0,trcolour = 0,brcolour = 0,blcolour = 0; + + // scan column above + if (y > 0){ + tempy = y; + tempx = x; + tcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != tcolour || board[tempy][tempx] == 0) break; + tcount++; + if (tempy == 0) break; + tempy--; + } + } + // scan column below + if (y < 18){ + tempy = y+1; + tempx = x; + bcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != bcolour || board[tempy][tempx] == 0) break; + bcount++; + if (tempy == 18) break; + tempy++; + } + } + + if (tcolour == bcolour && tcount + bcount >= 6) return tcolour; + + // scan row to left + if (x > 0){ + tempy = y; + tempx = x; + lcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != lcolour || board[tempy][tempx] == 0) break; + lcount++; + if (tempx == 0) break; + tempx--; + } + } + // scan row to right + if (x < 18){ + tempy = y; + tempx = x+1; + rcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != rcolour || board[tempy][tempx] == 0) break; + rcount++; + if (tempx == 18) break; + tempx++; + } + } + + if (lcolour == rcolour && lcount + rcount >= 6) return lcolour; + + // scan diagonal topleft + if (x > 0 && y > 0){ + tempy = y; + tempx = x; + tlcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != tlcolour || board[tempy][tempx] == 0) break; + tlcount++; + if (tempx == 0 || tempy == 0) break; + tempx--; + tempy--; + } + } + // scan diagonal bottomright + if (x < 18 && y < 18){ + tempy = y+1; + tempx = x+1; + brcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != brcolour || board[tempy][tempx] == 0) break; + brcount++; + if (tempx == 18 || tempy == 18) break; + tempx++; + tempy++; + } + } + + if (tlcolour == brcolour && tlcount + brcount >= 6) return tlcolour; + + // scan diagonal topright + if (x < 18 && y > 0){ + tempy = y; + tempx = x; + trcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != trcolour || board[tempy][tempx] == 0) break; + trcount++; + if (tempx == 18 || tempy == 0) break; + tempx++; + tempy--; + } + } + // scan diagonal bottomleft + if (y < 18 && x > 0){ + tempy = y+1; + tempx = x-1; + blcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != blcolour || board[tempy][tempx] == 0) break; + blcount++; + if (tempy == 18 || tempx == 0) break; + tempy++; + tempx--; + } + } + + if (trcolour == blcolour && trcount + blcount >= 6) return trcolour; + } + } + // return 'n' for no victory + return 'n'; +} + +// Check if the board is full +int check_board_full (char board[][19]){ + int y,x; + // As soon as there is an empty intersection, return 0; + for (y = 0; y < 19; y++) + for (x = 0; x < 19; x++) + if (board[y][x] == 0) + return 0; + + // By now, swept entire board and all filled. + return -1; +} + +// Check if move y,x is valid. Here, y and x are [0 ... 18] +int check_move_validity (char board[][19],int y, int x){ + if (y < 0 || y > 18 || x < 0 || x > 18 || board[y][x] != 0){ + return -1; + } + return 0; +} + + +void print_board (char board[][19]){ + printf(" 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9"); + unsigned short x,y; + for (x = 0; x <= 18; x++){ + printf("\n"); + printf("%d",x+1); + if (x < 9) printf(" "); + for (y = 0; y <= 18; y++){ + if (board[x][y] == 0) + printf("."); + else printf("%c",board[x][y]); + printf(" "); + } + + } + printf("\n"); +} + +void print_board_file (char board[][19]){ +char *filename="myboard.txt"; +FILE *fp=fopen(filename,"w"); + fprintf(fp," 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9"); + unsigned short x,y; + for (x = 0; x <= 18; x++){ + fprintf(fp,"\n"); + fprintf(fp,"%d",x+1); + if (x < 9) fprintf(fp," "); + for (y = 0; y <= 18; y++){ + if (board[x][y] == 0) + fprintf(fp,"."); + else fprintf(fp,"%c",board[x][y]); + fprintf(fp," "); + } + + } + fprintf(fp,"\n"); +fclose(fp); +} Index: CONNECT6_CMDLINE/util.h =================================================================== --- CONNECT6_CMDLINE/util.h (nonexistent) +++ CONNECT6_CMDLINE/util.h (revision 5) @@ -0,0 +1,34 @@ +/* util.cpp + June 9, 2011 + Some helper functions. + + Much of the code below is borrowed from Alastair Smith's program + from the 2010 FPT Othello competition + + By Kevin Nam +*/ + +#ifndef _UTILS_H +#define _UTILS_H + +using namespace std; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include "commondefs.h" + +/*********************** Portable random number generators *******************/ + +void setup_port(int fd); +int select_com_port(int argc, char **argv); +char select_AI_colour (int argc, char **argv); +int char_to_int (char c); +void wait(double seconds); +#endif Index: CONNECT6_CMDLINE/connect6.h =================================================================== --- CONNECT6_CMDLINE/connect6.h (nonexistent) +++ CONNECT6_CMDLINE/connect6.h (revision 5) @@ -0,0 +1,19 @@ +/* + connect6.h + June 9, 2011 + This file contains the game AI + By Kevin Nam + +*/ + +#ifndef _CONNECT6_H +#define _CONNECT6_H + +int calculatepoints(char board[][19], int y, int x, char colour); +int connect6ai(char board[][19], char colour, char move[4]); +char check_for_win (char board[][19]); +int check_board_full (char board[][19]); +int check_move_validity (char board[][19],int y, int x); +void print_board (char board[][19]); +void print_board_file (char board[][19]); +#endif Index: CONNECT6_CMDLINE/connect6_synth.cpp =================================================================== --- CONNECT6_CMDLINE/connect6_synth.cpp (nonexistent) +++ CONNECT6_CMDLINE/connect6_synth.cpp (revision 5) @@ -0,0 +1,458 @@ +/* + connect6.cpp + June 9, 2011 + This file contains the game AI + By Kevin Nam + + */ + +//#include +//#include +// +//#include "util.h" +//#include "connect6.h" + +// Subtract this many points for moves at the edges. +#define EDGEPENALTY 5 + +using namespace std; + +/* The cost function simply counts all of the consecutive stones of same colour in + every direction from the spot for which the points is being calculated. + +Ex: + +.DDLL +.DLDD +DXDDD +...D. + +Above, X is the spot being calculated. +The points would be 2 (above) + 2(topright) + 3(right) + 1 (left) = 8. +It treats opponent's stones and own stones with equal weighting. + +Return 0 if the spot y,x is already taken, else return the calculated value + + */ + static int char_to_int(short x){ + if(x>=48) + return x-48; + else + return 0; + } + +static int calculatepoints_synth(unsigned char board[19][19], short y, short x, char colour8){ + #pragma bitsize x 6 + #pragma bitsize y 6 + short pts = 0, tempx = x, tempy = y, tcount = 0,bcount = 0; + #pragma bitsize pts 8 + #pragma bitsize tempx 6 + #pragma bitsize tempy 6 + #pragma bitsize tcount 3 + #pragma bitsize bcount 3 + + char lcount = 0,rcount = 0,trcount = 0,tlcount = 0,brcount = 0,blcount = 0; + #pragma bitsize rcount 3 + #pragma bitsize lcount 3 + #pragma bitsize trcount 3 + #pragma bitsize tlcount 3 + #pragma bitsize brcount 3 + #pragma bitsize blcount 3 + char tcolour = 0,bcolour = 0,lcolour = 0,rcolour = 0,tlcolour = 0,trcolour = 0,brcolour = 0,blcolour = 0; + #pragma bitsize rcolour 2 + #pragma bitsize lcolour 2 + #pragma bitsize trcolour 2 + #pragma bitsize tlcolour 2 + #pragma bitsize brcolour 2 + #pragma bitsize blcolour 2 + unsigned char colour; + #pragma bitsize colour 2 + colour= (colour8==68) ? 1 : 2; + + if (board[y][x] != 0) + return 0; + + // scan column above + if (y > 0){ + tempy = y-1; + tempx = x; + tcolour = board[tempy][tempx]; + for(tempy=y-1;tempy > y-6;tempy--){ + if (tempy == 0) break; + if (board[tempy][tempx] != tcolour || board[tempy][tempx] == 0) break; + tcount++; + } + } + + // // scan column above + // if (y > 0){ + // tempy = y-1; + // tempx = x; + // tcolour = board[tempy][tempx]; + // while (1){ + // if (board[tempy][tempx] != tcolour || board[tempy][tempx] == 0) break; + // tcount++; + // if (tempy == 0) break; + // tempy--; + // } + // } + // scan column below + if (y < 18){ + tempy = y+1; + tempx = x; + bcolour = board[tempy][tempx]; + for(tempy=y+1;tempy < y+6;tempy++){ + if (tempy == 18) break; + if (board[tempy][tempx] != bcolour || board[tempy][tempx] == 0) break; + bcount++; + } + } + // // scan column below + // if (y < 18){ + // tempy = y+1; + // tempx = x; + // bcolour = board[tempy][tempx]; + // while (1){ + // if (board[tempy][tempx] != bcolour || board[tempy][tempx] == 0) break; + // bcount++; + // if (tempy == 18) break; + // tempy++; + // } + // } + // scan row to left + if (x > 0){ + tempy = y; + tempx = x-1; + lcolour = board[tempy][tempx]; + for(tempx=x-1;tempx > x-6;tempx--){ + if (tempx == 0) break; + if (board[tempy][tempx] != lcolour || board[tempy][tempx] == 0) break; + lcount++; + } + } + // // scan row to left + // if (x > 0){ + // tempy = y; + // tempx = x-1; + // lcolour = board[tempy][tempx]; + // while (1){ + // if (board[tempy][tempx] != lcolour || board[tempy][tempx] == 0) break; + // lcount++; + // if (tempx == 0) break; + // tempx--; + // } + // } + // scan row to right + if (x < 18){ + tempy = y; + tempx = x+1; + rcolour = board[tempy][tempx]; + for(tempx=x+1;tempx < x+6;tempx++){ + if (tempx == 18) break; + if (board[tempy][tempx] != rcolour || board[tempy][tempx] == 0) break; + rcount++; + } + } + // // scan row to right + // if (x < 18){ + // tempy = y; + // tempx = x+1; + // rcolour = board[tempy][tempx]; + // while (1){ + // if (board[tempy][tempx] != rcolour || board[tempy][tempx] == 0) break; + // rcount++; + // if (tempx == 18) break; + // tempx++; + // } + // } + // scan diagonal topleft + if (x > 0 && y > 0){ + tempy = y-1; + tempx = x-1; + tlcolour = board[tempy][tempx]; + while ((tempx > x-6) && (tempy > y-6)){ + if (tempx == 0 || tempy == 0) break; + if (board[tempy][tempx] != tlcolour || board[tempy][tempx] == 0) break; + tlcount++; + tempx--; + tempy--; + } + } + // scan diagonal bottomright + if (x < 18 && y < 18){ + tempy = y+1; + tempx = x+1; + brcolour = board[tempy][tempx]; + while ((tempx < x+6) && (tempy < y+6)){ + if (tempx == 18 || tempy == 18) break; + if (board[tempy][tempx] != brcolour || board[tempy][tempx] == 0) break; + brcount++; + tempx++; + tempy++; + } + } + // scan diagonal topright + if (x < 18 && y > 0){ + tempy = y-1; + tempx = x+1; + trcolour = board[tempy][tempx]; + while ((tempx < x+6) && (tempy > y-6)){ + if (tempx == 18 || tempy == 0) break; + if (board[tempy][tempx] != trcolour || board[tempy][tempx] == 0) break; + trcount++; + tempx++; + tempy--; + } + } + // scan diagonal bottomleft + if (y < 18 && x > 0){ + tempy = y+1; + tempx = x-1; + blcolour = board[tempy][tempx]; + while ((tempx > x-6) && (tempy < y+6)){ + if (tempy == 18 || tempx == 0) break; + if (board[tempy][tempx] != blcolour || board[tempy][tempx] == 0) break; + blcount++; + tempy++; + tempx--; + } + } + + /// Now calculate the points + // Check if this is a winning move. Priority #1. + if ((tcount >= 5 && tcolour == colour) || + (bcount >= 5 && bcolour == colour) || + (lcount >= 5 && lcolour == colour) || + (rcount >= 5 && rcolour == colour) || + (tlcount >= 5 && tlcolour == colour) || + (trcount >= 5 && trcolour == colour) || + (brcount >= 5 && brcolour == colour) || + (blcount >= 5 && blcolour == colour) || + (tcount + bcount >= 5 && tcolour == colour && bcolour == colour) || + (lcount + rcount >= 5 && lcolour == colour && rcolour == colour) || + (tlcount + brcount >= 5 && tlcolour == colour && brcolour == colour) || + (trcount + blcount >= 5 && trcolour == colour && blcolour == colour)) + return 1000; + + // Check if this move can stop opponent from winning. This move is priority #2. + if ((tcount >= 4 && tcolour != colour) || + (bcount >= 4 && bcolour != colour) || + (lcount >= 4 && lcolour != colour) || + (rcount >= 4 && rcolour != colour) || + (tlcount >= 4 && tlcolour != colour) || + (trcount >= 4 && trcolour != colour) || + (brcount >= 4 && brcolour != colour) || + (blcount >= 4 && blcolour != colour) || + (tcount + bcount >= 4 && tcolour != colour && bcolour != colour) || + (lcount + rcount >= 4 && lcolour != colour && rcolour != colour) || + (tlcount + brcount >= 4 && tlcolour != colour && brcolour != colour) || + (trcount + blcount >= 4 && trcolour != colour && blcolour != colour)) + return 500; + + // Else sum up the counts, use this as the points. + pts = tcount + bcount + lcount + rcount + tlcount + trcount + blcount + brcount + 1; + // If at an edge, lower the points + if (x == 0 || x == 18 || y == 0 || y == 18){ + if (pts >= EDGEPENALTY) + pts -= EDGEPENALTY; + else + pts = 0; + } + return pts; +} + +/* + The AI Function that calls the cost function for every spot on the board. + It returns the location with the highest points. In the event of a tie, randomly decide. + Input the board and the colour being played. + Puts the move (in ASCII chars) inside move[4]. This is from [1 ... 19] + Puts the move (in integers) in moveY and moveX. This is from [0 ... 18] + */ +int connect6ai_synth(int firstmove,char movein[8], char colour, char moveout[8]){ + #pragma bitsize firstmove 8 + short x,y,highx = 0, highy = 0,currenthigh = 0, temp; + #pragma bitsize x 6 + #pragma bitsize y 6 + #pragma bitsize highx 6 + #pragma bitsize highy 6 + #pragma bitsize currenthigh 6 + #pragma bitsize temp 6 // one bit more for short + //srand(time(NULL)); + static unsigned char myboard[19][19] ;//= {{ 0 }}; + #pragma bitsize myboard 2 + #pragma internal_blockram myboard + #pragma preserve_array myboard + char highRandom = 1;//rand(); + #pragma bitsize highRandom 2 + if(firstmove==0 || firstmove ==1){ + int i,j; + for (i=0;i<19;i++) + for (j=0;j<19;j++) + myboard[i][j]=0; + } + //------------------------------------------------------------------------- + if((firstmove >= 1)){ + //update the board + y = char_to_int(movein[0])*10 + char_to_int(movein[1]) - 1; + x = char_to_int(movein[2])*10 + char_to_int(movein[3]) - 1; + if(colour==68)//'D') + myboard[y][x] = (char)2;//76;//'L'; + else + myboard[y][x] = (char)1;//68;//'D'; + } + if((firstmove >=3)){ + //update the board + y = char_to_int(movein[4])*10 + char_to_int(movein[5]) - 1; + x = char_to_int(movein[6])*10 + char_to_int(movein[7]) - 1; + if(colour==68)//'D') + myboard[y][x] = (char)2;//76;//'L'; + else + myboard[y][x] = (char)1;//68;//'D'; + } + //printf("MYBOARD\n"); + //print_board(myboard); + // Sweep the entire myboard with the cost function + for (x = 0; x <= 18; x++){ + for (y = 0; y <= 18; y++){ + + temp = calculatepoints_synth(myboard,y,x, colour); + if (temp > currenthigh){ + highx = x; + highy = y; + currenthigh = temp; + highRandom =1;// rand(); + } + // If a tie happens, pseudo-randomly choose one between them + if (temp == currenthigh && temp != 0){ + int tempRandom = 1;//rand(); + if (tempRandom > highRandom){ + highx = x; + highy = y; + highRandom = tempRandom; + } + } + } + } + + // Modify the myboard based on current move. + + myboard[highy][highx] = (colour==68) ? 1 : 2 ; + + // Increment by 1 because indexing starts at 1. + highy++; + highx++; + + /// Convert the int coordinates to corresponding ASCII chars + if (highy >= 10){ + moveout[0] = '1'; + highy -= 10; + } else { + moveout[0] = '0'; + } + if (highy == 0) moveout[1] = '0'; + else if (highy == 1) moveout[1] = '1'; + else if (highy == 2) moveout[1] = '2'; + else if (highy == 3) moveout[1] = '3'; + else if (highy == 4) moveout[1] = '4'; + else if (highy == 5) moveout[1] = '5'; + else if (highy == 6) moveout[1] = '6'; + else if (highy == 7) moveout[1] = '7'; + else if (highy == 8) moveout[1] = '8'; + else if (highy == 9) moveout[1] = '9'; + + // Do same for x. + if (highx >= 10){ + moveout[2] = '1'; + highx -= 10; + } else { + moveout[2] = '0'; + } + if (highx == 0) moveout[3] = '0'; + else if (highx == 1) moveout[3] = '1'; + else if (highx == 2) moveout[3] = '2'; + else if (highx == 3) moveout[3] = '3'; + else if (highx == 4) moveout[3] = '4'; + else if (highx == 5) moveout[3] = '5'; + else if (highx == 6) moveout[3] = '6'; + else if (highx == 7) moveout[3] = '7'; + else if (highx == 8) moveout[3] = '8'; + else if (highx == 9) moveout[3] = '9'; + //------------------------------------------------------------------------- + highx = 0; highy = 0;currenthigh = 0; highRandom = 1; + //------------------------------------------------------------------------- + if(firstmove>=1){ + // Sweep the entire myboard with the cost function + for (x = 0; x <= 18; x++){ + for (y = 0; y <= 18; y++){ + //printf("%d %d\n",y,x); + temp = calculatepoints_synth(myboard,y,x, colour); + //printf("%d \n",temp); + if (temp > currenthigh){ + highx = x; + highy = y; + currenthigh = temp; + highRandom = 1;//rand(); + } + // If a tie happens, pseudo-randomly choose one between them + if (temp == currenthigh && temp != 0){ + int tempRandom = 1;//rand(); + if (tempRandom > highRandom){ + highx = x; + highy = y; + highRandom = tempRandom; + } + } + } + } + + // Modify the myboard based on current move. + myboard[highy][highx] = (colour==68) ? 1 :2 ; + + // Increment by 1 because indexing starts at 1. + highy++; + highx++; + + /// Convert the int coordinates to corresponding ASCII chars + if (highy >= 10){ + moveout[4] = '1'; + highy -= 10; + } else { + moveout[4] = '0'; + } + if (highy == 0) moveout[5] = '0'; + else if (highy == 1) moveout[5] = '1'; + else if (highy == 2) moveout[5] = '2'; + else if (highy == 3) moveout[5] = '3'; + else if (highy == 4) moveout[5] = '4'; + else if (highy == 5) moveout[5] = '5'; + else if (highy == 6) moveout[5] = '6'; + else if (highy == 7) moveout[5] = '7'; + else if (highy == 8) moveout[5] = '8'; + else if (highy == 9) moveout[5] = '9'; + + // Do same for x. + if (highx >= 10){ + moveout[6] = '1'; + highx -= 10; + } else { + moveout[6] = '0'; + } + if (highx == 0) moveout[7] = '0'; + else if (highx == 1) moveout[7] = '1'; + else if (highx == 2) moveout[7] = '2'; + else if (highx == 3) moveout[7] = '3'; + else if (highx == 4) moveout[7] = '4'; + else if (highx == 5) moveout[7] = '5'; + else if (highx == 6) moveout[7] = '6'; + else if (highx == 7) moveout[7] = '7'; + else if (highx == 8) moveout[7] = '8'; + else if (highx == 9) moveout[7] = '9'; + } + //------------------------------------------------------------------------- + //int i; + //for(i=0;i<8;i++) printf("%c",moveout[i]); + return 0; +} + + + Index: CONNECT6_CMDLINE/main.cpp =================================================================== --- CONNECT6_CMDLINE/main.cpp (nonexistent) +++ CONNECT6_CMDLINE/main.cpp (revision 5) @@ -0,0 +1,276 @@ +/* main.cpp + June 9,2011 + + Software connect6 AI program. + Have your board polling for its colour before starting this program. + + commandline option: + -port + Ex: "./connect6 -port /dev/ttyUSB0" + + By: Kevin Nam +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "util.h" +#include "connect6.h" +#include "connect6_synth.h" +#include "connect6_golden.h" +//#include "pico.h" + +// The AI has as much time as it wants, but moves after 1 second. Default is to wait 2 seconds +#define AI_WAIT_TIME 0.1 + +// FPGA has 1 second to make its move +#define MOVE_TIME_LIMIT 0.1 + +using namespace std; + +// commandline option: -port +int main(int argc, char **argv){ + //for verification two runs and a reference board + int i,j,k; + char ref_board[19][19] = {{ 0 }}; + + char board[19][19] = {{ 0 }}; + char move[4]; + char moveport[8]={0}; + char moveportout[8]={0}; + int movecount=0; + int y,x; + char winning_colour; + + // Get the serial port + int port = select_com_port(argc,argv); + // Get software AI's colour + char AI_colour = select_AI_colour(argc,argv); + char FPGA_colour; +// int id = PICO_initialize_PPA(connect6ai_synth); + // Take care of the first few moves (including sending the colour) + if (AI_colour == 'D'){ + FPGA_colour = 'L'; + write(port, "L",1); + + wait(AI_WAIT_TIME); + + // AI makes a move + connect6ai(board,AI_colour,move); + movecount++; + cout<<"AI MOVE: "< +#include + +#include "util.h" +#include "connect6.h" + +// Subtract this many points for moves at the edges. +#define EDGEPENALTY 5 + +using namespace std; + +/* The cost function simply counts all of the consecutive stones of same colour in + every direction from the spot for which the points is being calculated. + + Ex: + + .DDLL + .DLDD + DXDDD + ...D. + + Above, X is the spot being calculated. + The points would be 2 (above) + 2(topright) + 3(right) + 1 (left) = 8. + It treats opponent's stones and own stones with equal weighting. + + Return 0 if the spot y,x is already taken, else return the calculated value + +*/ +static int calculatepoints_golden(char board[][19], int y, int x, char colour){ + int pts = 0, tempx = x, tempy = y, tcount = 0,bcount = 0; + int lcount = 0,rcount = 0,trcount = 0,tlcount = 0,brcount = 0,blcount = 0; + char tcolour = 0,bcolour = 0,lcolour = 0,rcolour = 0,tlcolour = 0,trcolour = 0,brcolour = 0,blcolour = 0; + + if (board[y][x] != 0) + return 0; + + // scan column above + if (y > 0){ + tempy = y-1; + tempx = x; + tcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != tcolour || board[tempy][tempx] == 0) break; + tcount++; + if (tempy == 0) break; + tempy--; + } + } + // scan column below + if (y < 18){ + tempy = y+1; + tempx = x; + bcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != bcolour || board[tempy][tempx] == 0) break; + bcount++; + if (tempy == 18) break; + tempy++; + } + } + // scan row to left + if (x > 0){ + tempy = y; + tempx = x-1; + lcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != lcolour || board[tempy][tempx] == 0) break; + lcount++; + if (tempx == 0) break; + tempx--; + } + } + // scan row to right + if (x < 18){ + tempy = y; + tempx = x+1; + rcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != rcolour || board[tempy][tempx] == 0) break; + rcount++; + if (tempx == 18) break; + tempx++; + } + } + // scan diagonal topleft + if (x > 0 && y > 0){ + tempy = y-1; + tempx = x-1; + tlcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != tlcolour || board[tempy][tempx] == 0) break; + tlcount++; + if (tempx == 0 || tempy == 0) break; + tempx--; + tempy--; + } + } + // scan diagonal bottomright + if (x < 18 && y < 18){ + tempy = y+1; + tempx = x+1; + brcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != brcolour || board[tempy][tempx] == 0) break; + brcount++; + if (tempx == 18 || tempy == 18) break; + tempx++; + tempy++; + } + } + // scan diagonal topright + if (x < 18 && y > 0){ + tempy = y-1; + tempx = x+1; + trcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != trcolour || board[tempy][tempx] == 0) break; + trcount++; + if (tempx == 18 || tempy == 0) break; + tempx++; + tempy--; + } + } + // scan diagonal bottomleft + if (y < 18 && x > 0){ + tempy = y+1; + tempx = x-1; + blcolour = board[tempy][tempx]; + while (1){ + if (board[tempy][tempx] != blcolour || board[tempy][tempx] == 0) break; + blcount++; + if (tempy == 18 || tempx == 0) break; + tempy++; + tempx--; + } + } + + /// Now calculate the points + // Check if this is a winning move. Priority #1. + if ((tcount >= 5 && tcolour == colour) || + (bcount >= 5 && bcolour == colour) || + (lcount >= 5 && lcolour == colour) || + (rcount >= 5 && rcolour == colour) || + (tlcount >= 5 && tlcolour == colour) || + (trcount >= 5 && trcolour == colour) || + (brcount >= 5 && brcolour == colour) || + (blcount >= 5 && blcolour == colour) || + (tcount + bcount >= 5 && tcolour == colour && bcolour == colour) || + (lcount + rcount >= 5 && lcolour == colour && rcolour == colour) || + (tlcount + brcount >= 5 && tlcolour == colour && brcolour == colour) || + (trcount + blcount >= 5 && trcolour == colour && blcolour == colour)) + return 1000; + + // Check if this move can stop opponent from winning. This move is priority #2. + if ((tcount >= 4 && tcolour != colour) || + (bcount >= 4 && bcolour != colour) || + (lcount >= 4 && lcolour != colour) || + (rcount >= 4 && rcolour != colour) || + (tlcount >= 4 && tlcolour != colour) || + (trcount >= 4 && trcolour != colour) || + (brcount >= 4 && brcolour != colour) || + (blcount >= 4 && blcolour != colour) || + (tcount + bcount >= 4 && tcolour != colour && bcolour != colour) || + (lcount + rcount >= 4 && lcolour != colour && rcolour != colour) || + (tlcount + brcount >= 4 && tlcolour != colour && brcolour != colour) || + (trcount + blcount >= 4 && trcolour != colour && blcolour != colour)) + return 500; + + // Else sum up the counts, use this as the points. + pts = tcount + bcount + lcount + rcount + tlcount + trcount + blcount + brcount + 1; + // If at an edge, lower the points + if (x == 0 || x == 18 || y == 0 || y == 18){ + if (pts >= EDGEPENALTY) + pts -= EDGEPENALTY; + else + pts = 0; + } + return pts; +} + +/* + The AI Function that calls the cost function for every spot on the board. + It returns the location with the highest points. In the event of a tie, randomly decide. + Input the board and the colour being played. + Puts the move (in ASCII chars) inside move[4]. This is from [1 ... 19] + Puts the move (in integers) in moveY and moveX. This is from [0 ... 18] +*/ +int connect6ai_golden(char board[][19], char colour, char move[4]){ + int x,y,highx = 0, highy = 0,currenthigh = 0, temp; + srand(time(NULL)); + int highRandom = 1;//rand(); + // Sweep the entire board with the cost function + for (x = 0; x <= 18; x++){ + for (y = 0; y <= 18; y++){ + + temp = calculatepoints_golden(board,y,x, colour); + if (temp > currenthigh){ + highx = x; + highy = y; + currenthigh = temp; + highRandom = 1;//rand(); + } + // If a tie happens, pseudo-randomly choose one between them + if (temp == currenthigh && temp != 0){ + int tempRandom = 1;//rand(); + if (tempRandom > highRandom){ + highx = x; + highy = y; + highRandom = tempRandom; + } + } + } + } + + // Modify the board based on current move. + //board[highy][highx] = colour; + + // Increment by 1 because indexing starts at 1. + highy++; + highx++; + + /// Convert the int coordinates to corresponding ASCII chars + if (highy >= 10){ + move[0] = '1'; + highy -= 10; + } else { + move[0] = '0'; + } + if (highy == 0) move[1] = '0'; + else if (highy == 1) move[1] = '1'; + else if (highy == 2) move[1] = '2'; + else if (highy == 3) move[1] = '3'; + else if (highy == 4) move[1] = '4'; + else if (highy == 5) move[1] = '5'; + else if (highy == 6) move[1] = '6'; + else if (highy == 7) move[1] = '7'; + else if (highy == 8) move[1] = '8'; + else if (highy == 9) move[1] = '9'; + + // Do same for x. + if (highx >= 10){ + move[2] = '1'; + highx -= 10; + } else { + move[2] = '0'; + } + if (highx == 0) move[3] = '0'; + else if (highx == 1) move[3] = '1'; + else if (highx == 2) move[3] = '2'; + else if (highx == 3) move[3] = '3'; + else if (highx == 4) move[3] = '4'; + else if (highx == 5) move[3] = '5'; + else if (highx == 6) move[3] = '6'; + else if (highx == 7) move[3] = '7'; + else if (highx == 8) move[3] = '8'; + else if (highx == 9) move[3] = '9'; + + return 0; +} + + + Index: CONNECT6_CMDLINE/connect6_synth.h =================================================================== --- CONNECT6_CMDLINE/connect6_synth.h (nonexistent) +++ CONNECT6_CMDLINE/connect6_synth.h (revision 5) @@ -0,0 +1,5 @@ +#ifndef _CONNECT6_H_SYNTH +#define _CONNECT6_H_SYNTH + +int connect6ai_synth(int firstmove,char movein[8], char colour, char moveout[8]); +#endif Index: CONNECT6_CMDLINE/Makefile =================================================================== --- CONNECT6_CMDLINE/Makefile (nonexistent) +++ CONNECT6_CMDLINE/Makefile (revision 5) @@ -0,0 +1,23 @@ +SRC=./ +GCC=g++ +all: fpt_connect6 test + +fpt_connect6: ${SRC}/main.cpp util.o connect6.o connect6_synth.o + ${GCC} -o connect6 ${SRC}/main.cpp util.o connect6.o connect6_synth.o -lpthread -lm -g -pg + cp connect6 ../DEMO + +connect6_synth.o: ${SRC}/connect6_synth.cpp ${SRC}/connect6_synth.h + ${GCC} -c -g -pg ${SRC}/connect6_synth.cpp +connect6.o: ${SRC}/connect6.cpp ${SRC}/connect6.h + ${GCC} -c -g -pg ${SRC}/connect6.cpp + +util.o: ${SRC}/util.cpp ${SRC}/util.h + ${GCC} -c -g -pg ${SRC}/util.cpp + + + +test: + ./connect6 -player L -port /dev/ttyS0 + +clean: + rm -f *.o connect6 gmon.out myboard.txt Index: CONNECT6_CMDLINE/connect6_golden.h =================================================================== --- CONNECT6_CMDLINE/connect6_golden.h (nonexistent) +++ CONNECT6_CMDLINE/connect6_golden.h (revision 5) @@ -0,0 +1,5 @@ +#ifndef _CONNECT6_H_GOLDEN +#define _CONNECT6_H_GOLDEN + +int connect6ai_golden(char board[][19], char colour, char move[4]); +#endif Index: CONNECT6_CMDLINE/util.cpp =================================================================== --- CONNECT6_CMDLINE/util.cpp (nonexistent) +++ CONNECT6_CMDLINE/util.cpp (revision 5) @@ -0,0 +1,131 @@ +/* util.cpp + June 9, 2011 + Some helper functions. + + Much of the code below is borrowed from Alastair Smith's program + from the 2010 FPT Othello competition + + By Kevin Nam +*/ + + +#include +#include +#include +#include +#include +#include +#include "util.h" + +#define IA 1103515245u +#define IC 12345u +#define IM 2147483648u + +using namespace std; + +static unsigned int current_random = 0; + + +char select_AI_colour (int argc, char **argv){ + char ai_colour; + int i; + //cout<<"Please enter referee AI's colour. L or D"<> ai_colour; + for(i=0;i> ai_colour; + } + + cout<<"AI is playing as "<> com_port; + } + + + port = open(com_port.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); + while(port < 0) // if open is unsucessful keep trying until the user specifies a good port + { + cout << "Unable to open port " << com_port << ", try again, should be: (windows) /dev/comx or (linux) /dev/ttyx ?\n"; + cin >> com_port; + port = open(com_port.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); + } + setup_port(port); + + cout << "COM port has been set up at a baud rate of 115200\n"; + return port; +} + +void setup_port(int fd) { + struct termios options; + fcntl(fd, F_SETFL, 0); + tcgetattr(fd, &options); + cfsetispeed(&options, B115200); + cfsetospeed(&options, B115200); + options.c_cflag |= (CLOCAL | CREAD); + tcsetattr(fd, TCSANOW, &options); + + // set up non-blocking port, so that we can time out + int opts; + opts = fcntl(fd,F_GETFL); + if (opts < 0) { + perror("fcntl(F_GETFL)"); + exit(EXIT_FAILURE); + } + opts = (opts | O_NONBLOCK); + if (fcntl(fd,F_SETFL,opts) < 0) { + perror("fcntl(F_SETFL)"); + exit(EXIT_FAILURE); + } + return; +} + +int char_to_int (char c){ + if (c == '0') return 0; + else if (c == '1') return 1; + else if (c == '2') return 2; + else if (c == '3') return 3; + else if (c == '4') return 4; + else if (c == '5') return 5; + else if (c == '6') return 6; + else if (c == '7') return 7; + else if (c == '8') return 8; + else if (c == '9') return 9; + + return 0; +} + +void wait(double seconds){ + timeval tim; + gettimeofday(&tim, NULL); + double t1=tim.tv_sec+(tim.tv_usec/1000000.0); + while (1){ + gettimeofday(&tim, NULL); + double t2=tim.tv_sec+(tim.tv_usec/1000000.0); + if (t2-t1 >= seconds) + break; + } +} +

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.