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;
+ }
+}
+