/* main.cpp
|
/* main.cpp
|
June 9,2011
|
June 9,2011
|
|
|
Software connect6 AI program.
|
Software connect6 AI program.
|
Have your board polling for its colour before starting this program.
|
Have your board polling for its colour before starting this program.
|
|
|
commandline option:
|
commandline option:
|
-port <serialport>
|
-port <serialport>
|
Ex: "./connect6 -port /dev/ttyUSB0"
|
Ex: "./connect6 -port /dev/ttyUSB0"
|
|
|
By: Kevin Nam
|
By: Kevin Nam
|
*/
|
*/
|
|
|
#include <iostream>
|
#include <iostream>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <string.h>
|
#include <string.h>
|
#include <unistd.h>
|
#include <unistd.h>
|
#include <fcntl.h>
|
#include <fcntl.h>
|
#include <errno.h>
|
#include <errno.h>
|
#include <termios.h>
|
#include <termios.h>
|
#include <sys/time.h>
|
#include <sys/time.h>
|
#include "util.h"
|
#include "util.h"
|
#include "connect6.h"
|
#include "connect6.h"
|
#include "connect6_synth.h"
|
#include "connect6_synth.h"
|
#ifndef EMUL
|
#ifndef EMUL
|
#include "pico.h"
|
#include "pico.h"
|
#endif
|
#endif
|
#include "shared.h"
|
#include "shared.h"
|
|
|
#ifndef EMUL
|
|
// The AI has as much time as it wants, but moves after 1 second. Default is to wait 2 seconds
|
// 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
|
#define AI_WAIT_TIME 0.1
|
|
|
// FPGA has 1 second to make its move
|
// FPGA has 1 second to make its move
|
#define MOVE_TIME_LIMIT 0.1
|
#define MOVE_TIME_LIMIT 0.1
|
#endif
|
|
|
|
#ifdef EMUL
|
|
// 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 1
|
|
#endif
|
|
using namespace std;
|
using namespace std;
|
extern "C" int main(int argc, char **argv);
|
extern "C" int main(int argc, char **argv);
|
// commandline option: -port <serialport>
|
// commandline option: -port <serialport>
|
int main(int argc, char **argv){
|
int main(int argc, char **argv){
|
//for verification two runs and a reference board
|
//for verification two runs and a reference board
|
int i,j,k;
|
int i,j,k;
|
char ref_board[19][19] = {{ 0 }};
|
char ref_board[19][19] = {{ 0 }};
|
|
|
char board[19][19] = {{ 0 }};
|
char board[19][19] = {{ 0 }};
|
char move[4];
|
char move[4];
|
char moveport[8]={0};
|
char moveport[8]={0};
|
char moveportout[8]={0};
|
char moveportout[8]={0};
|
int movecount=0;
|
int movecount=0;
|
int y,x;
|
int y,x;
|
char winning_colour;
|
char winning_colour;
|
|
|
#ifdef EMUL
|
#ifdef EMUL
|
// Get the serial port
|
// Get the serial port
|
int port = select_com_port(argc,argv);
|
int port = select_com_port(argc,argv);
|
#endif
|
#endif
|
// Get software AI's colour
|
// Get software AI's colour
|
char AI_colour = select_AI_colour(argc,argv);
|
char AI_colour = select_AI_colour(argc,argv);
|
char FPGA_colour;
|
char FPGA_colour;
|
#ifndef EMUL
|
#ifndef EMUL
|
int id = PICO_initialize_PPA(connect6ai_synth);
|
int id = PICO_initialize_PPA(connect6ai_synth);
|
#endif
|
#endif
|
// Take care of the first few moves (including sending the colour)
|
// Take care of the first few moves (including sending the colour)
|
if (AI_colour == 'D'){
|
if (AI_colour == 'D'){
|
FPGA_colour = 'L';
|
FPGA_colour = 'L';
|
#ifdef EMUL
|
#ifdef EMUL
|
write(port, "L",1);
|
write(port, "L",1);
|
#endif
|
#endif
|
|
|
wait(AI_WAIT_TIME);
|
wait(AI_WAIT_TIME);
|
|
|
// AI makes a move
|
// AI makes a move
|
connect6ai(board,AI_colour,move);
|
connect6ai(board,AI_colour,move);
|
movecount++;
|
movecount++;
|
cout<<"AI MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl;
|
cout<<"AI MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl;
|
#ifdef EMUL
|
#ifdef EMUL
|
write(port,&move[0],1);
|
write(port,&move[0],1);
|
write(port,&move[1],1);
|
write(port,&move[1],1);
|
write(port,&move[2],1);
|
write(port,&move[2],1);
|
write(port,&move[3],1);
|
write(port,&move[3],1);
|
#endif
|
#endif
|
print_board(board);
|
print_board(board);
|
print_board_file(board);
|
print_board_file(board);
|
|
|
moveport[0]=move[0];
|
moveport[0]=move[0];
|
moveport[1]=move[1];
|
moveport[1]=move[1];
|
moveport[2]=move[2];
|
moveport[2]=move[2];
|
moveport[3]=move[3];
|
moveport[3]=move[3];
|
|
|
moveport[4]=0;
|
moveport[4]=0;
|
moveport[5]=0;
|
moveport[5]=0;
|
moveport[6]=0;
|
moveport[6]=0;
|
moveport[7]=0;
|
moveport[7]=0;
|
|
|
} else {
|
} else {
|
FPGA_colour = 'D';
|
FPGA_colour = 'D';
|
#ifdef EMUL
|
#ifdef EMUL
|
write(port, "D",1);
|
write(port, "D",1);
|
#endif
|
#endif
|
wait(MOVE_TIME_LIMIT);
|
wait(MOVE_TIME_LIMIT);
|
|
|
move[0] = 0; move[1] = 0; move[2] = 0; move[3] = 0;
|
move[0] = 0; move[1] = 0; move[2] = 0; move[3] = 0;
|
////////// Get Opponent's move
|
////////// Get Opponent's move
|
#ifdef EMUL
|
#ifdef EMUL
|
read(port,&move[0],1);
|
read(port,&move[0],1);
|
read(port,&move[1],1);
|
read(port,&move[1],1);
|
read(port,&move[2],1);
|
read(port,&move[2],1);
|
read(port,&move[3],1);
|
read(port,&move[3],1);
|
#endif
|
#endif
|
// FPGA makes a move
|
// FPGA makes a move
|
connect6ai_synth(movecount,moveport,FPGA_colour,moveportout);
|
connect6ai_synth(movecount,moveport,FPGA_colour,moveportout);
|
movecount++;
|
movecount++;
|
#ifndef EMUL
|
#ifndef EMUL
|
move[0]=moveportout[0];move[1]=moveportout[1];move[2]=moveportout[2];move[3]=moveportout[3];
|
move[0]=moveportout[0];move[1]=moveportout[1];move[2]=moveportout[2];move[3]=moveportout[3];
|
//connect6ai_golden(board,FPGA_colour,move);
|
//connect6ai_golden(board,FPGA_colour,move);
|
#endif
|
#endif
|
if (move[0] == 0 || move[1] == 0 || move[2] == 0 || move[3] == 0){
|
if (move[0] == 0 || move[1] == 0 || move[2] == 0 || move[3] == 0){
|
cout<<"FPGA has not completed a move in 1 second. Exiting."<<endl;
|
cout<<"FPGA has not completed a move in 1 second. Exiting."<<endl;
|
return 0;
|
return 0;
|
}
|
}
|
cout<<"FPGA MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl;
|
cout<<"FPGA MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl;
|
y = char_to_int(move[0])*10 + char_to_int(move[1]) - 1;
|
y = char_to_int(move[0])*10 + char_to_int(move[1]) - 1;
|
x = char_to_int(move[2])*10 + char_to_int(move[3]) - 1;
|
x = char_to_int(move[2])*10 + char_to_int(move[3]) - 1;
|
if (check_move_validity(board,y,x) < 0) return 0;
|
if (check_move_validity(board,y,x) < 0) return 0;
|
board[y][x] = FPGA_colour;
|
board[y][x] = FPGA_colour;
|
print_board(board);
|
print_board(board);
|
print_board_file(board);
|
print_board_file(board);
|
#ifdef EMUL
|
|
if(move[0]!=moveportout[0]||move[1]!=moveportout[1]||move[2]!=moveportout[2]||move[3]!=moveportout[3]) {
|
|
printf("EMULATION FAIL: BEHAVIOUR Doesn't match \"%c%c%c%c\" X \"%c%c%c%c\"\n",move[0],move[1],move[2],move[3],moveportout[0],moveportout[1],moveportout[2],moveportout[3]);
|
|
//exit(1);
|
|
}
|
|
#endif
|
|
wait(AI_WAIT_TIME);
|
wait(AI_WAIT_TIME);
|
|
|
|
|
// AI makes a move
|
// AI makes a move
|
connect6ai(board,AI_colour,move);
|
connect6ai(board,AI_colour,move);
|
movecount++;
|
movecount++;
|
cout<<"AI MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl;
|
cout<<"AI MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl;
|
#ifdef EMUL
|
#ifdef EMUL
|
write(port,&move[0],1);
|
write(port,&move[0],1);
|
write(port,&move[1],1);
|
write(port,&move[1],1);
|
write(port,&move[2],1);
|
write(port,&move[2],1);
|
write(port,&move[3],1);
|
write(port,&move[3],1);
|
#endif
|
#endif
|
moveport[0]=move[0];
|
moveport[0]=move[0];
|
moveport[1]=move[1];
|
moveport[1]=move[1];
|
moveport[2]=move[2];
|
moveport[2]=move[2];
|
moveport[3]=move[3];
|
moveport[3]=move[3];
|
// AI makes a move
|
// AI makes a move
|
connect6ai(board,AI_colour,move);
|
connect6ai(board,AI_colour,move);
|
movecount++;
|
movecount++;
|
cout<<"AI MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl;
|
cout<<"AI MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl;
|
#ifdef EMUL
|
#ifdef EMUL
|
write(port,&move[0],1);
|
write(port,&move[0],1);
|
write(port,&move[1],1);
|
write(port,&move[1],1);
|
write(port,&move[2],1);
|
write(port,&move[2],1);
|
write(port,&move[3],1);
|
write(port,&move[3],1);
|
#endif
|
#endif
|
moveport[4]=move[0];
|
moveport[4]=move[0];
|
moveport[5]=move[1];
|
moveport[5]=move[1];
|
moveport[6]=move[2];
|
moveport[6]=move[2];
|
moveport[7]=move[3];
|
moveport[7]=move[3];
|
print_board_file(board);
|
print_board_file(board);
|
}
|
}
|
|
|
// Alternate between receiving and sending moves
|
// Alternate between receiving and sending moves
|
while(1){
|
while(1){
|
wait(MOVE_TIME_LIMIT);
|
wait(MOVE_TIME_LIMIT);
|
|
|
// Get Opponent's move
|
// Get Opponent's move
|
move[0] = 0; move[1] = 0; move[2] = 0; move[3] = 0;
|
move[0] = 0; move[1] = 0; move[2] = 0; move[3] = 0;
|
#ifdef EMUL
|
#ifdef EMUL
|
read(port,&move[0],1);
|
read(port,&move[0],1);
|
read(port,&move[1],1);
|
read(port,&move[1],1);
|
read(port,&move[2],1);
|
read(port,&move[2],1);
|
read(port,&move[3],1);
|
read(port,&move[3],1);
|
#endif
|
#endif
|
connect6ai_synth(movecount,moveport,FPGA_colour,moveportout);
|
connect6ai_synth(movecount,moveport,FPGA_colour,moveportout);
|
movecount++;
|
movecount++;
|
#ifndef EMUL
|
#ifndef EMUL
|
move[0]=moveportout[0];move[1]=moveportout[1];move[2]=moveportout[2];move[3]=moveportout[3];
|
move[0]=moveportout[0];move[1]=moveportout[1];move[2]=moveportout[2];move[3]=moveportout[3];
|
#endif
|
#endif
|
//connect6ai_golden(board,FPGA_colour,move);
|
//connect6ai_golden(board,FPGA_colour,move);
|
|
|
cout<<"FPGA MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl;
|
cout<<"FPGA MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl;
|
if (move[0] == 0 || move[1] == 0 || move[2] == 0 || move[3] == 0){
|
if (move[0] == 0 || move[1] == 0 || move[2] == 0 || move[3] == 0){
|
cout<<"FPGA has not completed a move in 1 second. Exiting."<<endl;
|
cout<<"FPGA has not completed a move in 1 second. Exiting."<<endl;
|
break;
|
break;
|
}
|
}
|
y = char_to_int(move[0])*10 + char_to_int(move[1]) - 1;
|
y = char_to_int(move[0])*10 + char_to_int(move[1]) - 1;
|
x = char_to_int(move[2])*10 + char_to_int(move[3]) - 1;
|
x = char_to_int(move[2])*10 + char_to_int(move[3]) - 1;
|
#ifdef EMUL
|
|
if(move[0]!=moveportout[0]||move[1]!=moveportout[1]||move[2]!=moveportout[2]||move[3]!=moveportout[3]) {
|
|
printf("EMULATION FAIL: BEHAVIOUR Doesn't match \"%c%c%c%c\" X \"%c%c%c%c\"\n",move[0],move[1],move[2],move[3],moveportout[0],moveportout[1],moveportout[2],moveportout[3]);
|
|
//exit(1);
|
|
}
|
|
#endif
|
|
if (check_move_validity(board,y,x) < 0) break;
|
if (check_move_validity(board,y,x) < 0) break;
|
board[y][x] = FPGA_colour;
|
board[y][x] = FPGA_colour;
|
winning_colour = check_for_win(board);
|
winning_colour = check_for_win(board);
|
if (winning_colour == AI_colour){
|
if (winning_colour == AI_colour){
|
cout<<"AI has won!" << movecount << " moves " << "Exiting."<<endl;
|
cout<<"AI has won!" << movecount << " moves " << "Exiting."<<endl;
|
break;
|
break;
|
} else if (winning_colour == FPGA_colour){
|
} else if (winning_colour == FPGA_colour){
|
cout<<"FPGA has won! " << movecount << " moves " << "Exiting."<<endl;
|
cout<<"FPGA has won! " << movecount << " moves " << "Exiting."<<endl;
|
break;
|
break;
|
}
|
}
|
if (check_board_full(board) < 0){
|
if (check_board_full(board) < 0){
|
cout << "TIE " << movecount << " moves " << "Exiting."<<endl;
|
cout << "TIE " << movecount << " moves " << "Exiting."<<endl;
|
break;
|
break;
|
}
|
}
|
// Get Opponent's move
|
// Get Opponent's move
|
move[0] = 0; move[1] = 0; move[2] = 0; move[3] = 0;
|
move[0] = 0; move[1] = 0; move[2] = 0; move[3] = 0;
|
#ifdef EMUL
|
#ifdef EMUL
|
read(port,&move[0],1);
|
read(port,&move[0],1);
|
read(port,&move[1],1);
|
read(port,&move[1],1);
|
read(port,&move[2],1);
|
read(port,&move[2],1);
|
read(port,&move[3],1);
|
read(port,&move[3],1);
|
#endif
|
#endif
|
////connect6ai_synth(board,FPGA_colour,move);
|
////connect6ai_synth(board,FPGA_colour,move);
|
movecount++;
|
movecount++;
|
#ifndef EMUL
|
#ifndef EMUL
|
move[0]=moveportout[4];move[1]=moveportout[5];move[2]=moveportout[6];move[3]=moveportout[7];
|
move[0]=moveportout[4];move[1]=moveportout[5];move[2]=moveportout[6];move[3]=moveportout[7];
|
#endif
|
#endif
|
//connect6ai_golden(board,FPGA_colour,move);
|
//connect6ai_golden(board,FPGA_colour,move);
|
cout<<"FPGA MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl;
|
cout<<"FPGA MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl;
|
if (move[0] == 0 || move[1] == 0 || move[2] == 0 || move[3] == 0){
|
if (move[0] == 0 || move[1] == 0 || move[2] == 0 || move[3] == 0){
|
cout<<"FPGA has not completed a move in 1 second. Exiting."<<endl;
|
cout<<"FPGA has not completed a move in 1 second. Exiting."<<endl;
|
break;
|
break;
|
}
|
}
|
y = char_to_int(move[0])*10 + char_to_int(move[1]) - 1;
|
y = char_to_int(move[0])*10 + char_to_int(move[1]) - 1;
|
x = char_to_int(move[2])*10 + char_to_int(move[3]) - 1;
|
x = char_to_int(move[2])*10 + char_to_int(move[3]) - 1;
|
#ifdef EMUL
|
|
if(move[0]!=moveportout[4]||move[1]!=moveportout[5]||move[2]!=moveportout[6]||move[3]!=moveportout[7]) {
|
|
printf("EMULATION FAIL: BEHAVIOUR Doesn't match \"%c%c%c%c\" X \"%c%c%c%c\"\n",move[0],move[1],move[2],move[3],moveportout[4],moveportout[5],moveportout[6],moveportout[7]);
|
|
//exit(1);
|
|
}
|
|
#endif
|
|
if (check_move_validity(board,y,x) < 0) break;
|
if (check_move_validity(board,y,x) < 0) break;
|
board[y][x] = FPGA_colour;
|
board[y][x] = FPGA_colour;
|
winning_colour = check_for_win(board);
|
winning_colour = check_for_win(board);
|
if (winning_colour == AI_colour){
|
if (winning_colour == AI_colour){
|
cout<<"AI has won! " << movecount << " moves " << "Exiting."<<endl;
|
cout<<"AI has won! " << movecount << " moves " << "Exiting."<<endl;
|
break;
|
break;
|
} else if (winning_colour == FPGA_colour){
|
} else if (winning_colour == FPGA_colour){
|
cout<<"FPGA has won! " << movecount << " moves " << "Exiting."<<endl;
|
cout<<"FPGA has won! " << movecount << " moves " << "Exiting."<<endl;
|
break;
|
break;
|
}
|
}
|
if (check_board_full(board) < 0) {
|
if (check_board_full(board) < 0) {
|
cout << "TIE " << movecount << " moves " << "Exiting."<<endl;
|
cout << "TIE " << movecount << " moves " << "Exiting."<<endl;
|
break;
|
break;
|
}
|
}
|
print_board(board);
|
print_board(board);
|
print_board_file(board);
|
print_board_file(board);
|
|
|
wait(AI_WAIT_TIME);
|
wait(AI_WAIT_TIME);
|
|
|
// AI makes a move
|
// AI makes a move
|
connect6ai(board,AI_colour,move);
|
connect6ai(board,AI_colour,move);
|
movecount++;
|
movecount++;
|
cout<<"AI MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl;
|
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);
|
winning_colour = check_for_win(board);
|
if (winning_colour == AI_colour){
|
if (winning_colour == AI_colour){
|
cout<<"AI has won! " << movecount << " moves " << "Exiting."<<endl;
|
cout<<"AI has won! " << movecount << " moves " << "Exiting."<<endl;
|
break;
|
break;
|
} else if (winning_colour == FPGA_colour){
|
} else if (winning_colour == FPGA_colour){
|
cout<<"FPGA has won! " << movecount << " moves " << "Exiting."<<endl;
|
cout<<"FPGA has won! " << movecount << " moves " << "Exiting."<<endl;
|
break;
|
break;
|
}
|
}
|
if (check_board_full(board) < 0){
|
if (check_board_full(board) < 0){
|
cout << "TIE " << movecount << " moves " << "Exiting."<<endl;
|
cout << "TIE " << movecount << " moves " << "Exiting."<<endl;
|
break;
|
break;
|
}
|
}
|
#ifdef EMUL
|
#ifdef EMUL
|
write(port,&move[0],1);
|
write(port,&move[0],1);
|
write(port,&move[1],1);
|
write(port,&move[1],1);
|
write(port,&move[2],1);
|
write(port,&move[2],1);
|
write(port,&move[3],1);
|
write(port,&move[3],1);
|
#endif
|
#endif
|
moveport[0]=move[0];
|
moveport[0]=move[0];
|
moveport[1]=move[1];
|
moveport[1]=move[1];
|
moveport[2]=move[2];
|
moveport[2]=move[2];
|
moveport[3]=move[3];
|
moveport[3]=move[3];
|
// AI makes a move
|
// AI makes a move
|
connect6ai(board,AI_colour,move);
|
connect6ai(board,AI_colour,move);
|
movecount++;
|
movecount++;
|
cout<<"AI MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl;
|
cout<<"AI MOVE: "<<move[0]<<move[1]<<move[2]<<move[3]<<endl;
|
winning_colour = check_for_win(board);
|
winning_colour = check_for_win(board);
|
if (winning_colour == AI_colour){
|
if (winning_colour == AI_colour){
|
cout<<"AI has won! " << movecount << " moves " << "Exiting."<<endl;
|
cout<<"AI has won! " << movecount << " moves " << "Exiting."<<endl;
|
break;
|
break;
|
} else if (winning_colour == FPGA_colour){
|
} else if (winning_colour == FPGA_colour){
|
cout<<"FPGA has won! " << movecount << " moves " << "Exiting."<<endl;
|
cout<<"FPGA has won! " << movecount << " moves " << "Exiting."<<endl;
|
break;
|
break;
|
}
|
}
|
if (check_board_full(board) < 0) {
|
if (check_board_full(board) < 0) {
|
cout << "TIE " << movecount << " moves " << "Exiting."<<endl;
|
cout << "TIE " << movecount << " moves " << "Exiting."<<endl;
|
break;
|
break;
|
}
|
}
|
#ifdef EMUL
|
#ifdef EMUL
|
write(port,&move[0],1);
|
write(port,&move[0],1);
|
write(port,&move[1],1);
|
write(port,&move[1],1);
|
write(port,&move[2],1);
|
write(port,&move[2],1);
|
write(port,&move[3],1);
|
write(port,&move[3],1);
|
#endif
|
#endif
|
moveport[4]=move[0];
|
moveport[4]=move[0];
|
moveport[5]=move[1];
|
moveport[5]=move[1];
|
moveport[6]=move[2];
|
moveport[6]=move[2];
|
moveport[7]=move[3];
|
moveport[7]=move[3];
|
print_board(board);
|
print_board(board);
|
print_board_file(board);
|
print_board_file(board);
|
}
|
}
|
|
|
#ifndef EMUL
|
#ifndef EMUL
|
PICO_finalize_PPA(id);
|
PICO_finalize_PPA(id);
|
#endif
|
#endif
|
|
|
return 0;
|
return 0;
|
|
|
}
|
}
|
|
|