swag

Dependencies:   Motor Servo mbed_tictactoe

main.cpp

Committer:
mattsims12
Date:
2015-10-26
Revision:
5:e6f9086e0730
Parent:
4:6342714f3bc3
Child:
6:2e621e78ab77

File content as of revision 5:e6f9086e0730:

/*
Matthew Sims and Ryan Limjoco
Robot that plays you in tic tac toe
Shorr 1001
*/

#include "mbed.h"
#include "Motor.h"
#include "Servo.h"
#include "Timer.h"

DigitalIn in[]= {p16,p17,p18,p19,p20,p15};
DigitalOut lights[]= {p5,p6,p7,p8,p11};
Timer timer;
Motor m(p25,p27,p28);
Servo twist(p22);
Servo drop(p21);

int board[3][3];
int xglobal,yglobal; //Used to get 2 ints out of tworow
int xprev,yprev,xstart,ystart;   //Record Player's Previous move and the starting move of the ai

//Function Prototypes
int winner();                       //Checks winner and returns who won
void player(int chip);              //Player picks space
void ai(int chip,int difficulty);   //Ai picks space
int turn();                         //Determines the turn number(useful for difficulty 4)
bool tworow();                      //Checks for 2 in a row(for ai)
void perfectplace();                //Picks best spot to put a chip for difficulty 4
void playerpc(int chip);            //PC input for easier testing
void monitorout();                  //Sisplays the board in tera term for testing purposes
void placechip(int x, int y);       //Moves robot to place chip

int main()
{
    timer.start();  //Starts timer for the random seed
    twist.calibrate(.0009,90);
    drop.calibrate(.0009,90);
    twist=.75;
    drop=.8;

//Initialize board to -1
    for(int i=0; i<=2; i++) {
        for(int j=0; j<=2; j++) {
            board[i][j]=-1;
        }
    }

//User Selects Difficulty
    printf("Select Difficulty\n");
    int difficulty;
    //scanf("%d",&difficulty);
    
    while(in[0]+in[1]+in[2]+in[3]!=1) {
    }
    if(in[0]==1)
        difficulty=1;
    else if(in[1]==1)
        difficulty=2;
    else if(in[2]==1)
        difficulty=3;
    else if(in[3]==1)
        difficulty=4;

    lights[difficulty-1]=1;

    //Random Seed
    timer.stop();
    srand(timer.read_us());

//Pick who is x's and who is o's (0=o,1=x)
    int playerchip,aichip;
    playerchip=rand()%2;
    if(playerchip==0) {
        aichip=1;
        lights[4]=1;
    } else {
        aichip=0;
    }

//Loops of turns until someone wins or a tie
    if(playerchip==1) {
        printf("You go first\n");
        player(playerchip);
        //playerpc(playerchip);
    }
    while(true) {
        ai(aichip,difficulty);
        if(winner()!=-1)
            break;
        player(playerchip);
        //playerpc(playerchip);
    }

//Operates LED's based on winner
    int w=winner();
    printf("Winner:%d\n",w);
    lights[difficulty-1]=0;
    lights[4]=0;
    if(winner()==playerchip) { //Light Boucnes back and forth if player wins
        while(1) {
            for(int i=0; i<=4; i++) {
                lights[i]=1;
                wait(.2);
            }
            for(int i=4; i>=0; i--) {
                lights[i]=0;
                wait(.2);
            }
        }
    } else if(winner()==aichip) {
        while(1) {                      //All lights blink if ai wins
            for(int i=0; i<=4; i++) {
                lights[i]=!lights[i];
            }
            wait(.25);
        }
    } else {
        for(int i=0; i<=4; i++) { //Lights turn on solid if tue
            lights[i]=1;
        }
    }
}




//Checks to see if someone won
int winner()
{
    int winner=-1;
    //Horizontal and Vertical check
    for(int i=0; i<=2; i++) {
        if(board[i][0]==board[i][1] && board[i][0]==board[i][2] && board[i][0]!=-1)
            winner=board[i][0];
        if(board[0][i]==board[1][i] && board[0][i]==board[2][i] && board[0][i]!=-1)
            winner=board[0][i];
    }
    //Diagonal Checks
    if(board[0][0]==board[1][1] && board[0][0]==board[2][2] && board[0][0]!=-1)
        winner=board[0][0];
    if(board[0][2]==board[1][1] && board[0][2]==board[2][0] && board[0][2]!=-1)
        winner=board[0][2];

    return(winner);
}



//Player inputs using the switches until they pick an empty space
void player(int chip)
{
    int x=-1;
    int y=-1;
    do {
        if(in[0]+in[1]+in[2]==1 && in[3]+in[4]+in[5]==1) {
            if(in[0]==1)
                x=0;
            else if(in[1]==1)
                x=1;
            else if(in[2]==1)
                x=2;

            if(in[3]==1)
                y=0;
            else if(in[4]==1)
                y=1;
            else if(in[5]==1)
                y=2;
        }
    } while(board[x][y]!=-1);
    board[x][y]=chip;
    xprev=x;
    yprev=y;
    monitorout();
    //placechip(x,y);
}




//Counts filled spaces to determine how many turns have passed
int turn()
{
    int turn=9;
    for(int i=0; i<=2; i++) {
        for(int j=0; j<=2; j++) {
            if(board[i][j]==-1)
                turn--;
        }
    }
    return turn;
}




//Easy randomly picks any empty space on the board
void ai(int chip,int difficulty)
{
    int x,y;

    if(difficulty!=4) {
        do {
            x=rand()%2;
            y=rand()%2;
        } while(board[x][y]!=-1);

        if(difficulty==2 || difficulty==3) {      //Middle difficulties have a random chance of not blocking
            if(tworow()) {
                if((difficulty==2 && rand()%10<8) || difficulty==3) {    //Sometimes doesn't notice two in a row
                    x=xglobal;
                    y=yglobal;
                }
            }
        }
    } else {
        perfectplace();
        x=xglobal;
        y=yglobal;
    }
    //placechip(x,y);
    board[x][y]=chip;
    monitorout();
}



bool tworow()
{
    int x,y;
    //Vertical and horizontals
    for(int i=0; i<=2; i++) {
        if(board[0][i]==board[1][i] && board[2][i]==-1) {
            x=2;
            y=i; //board[2][i]
        } else if(board[1][i]==board[2][i] && board[0][i]==-1) {
            x=0;
            y=i; //board[0][i]
        } else if(board[0][i]==board[2][i] && board[1][i]==-1) {
            x=1;
            y=i; //board[1][i]
        } else if(board[i][0]==board[i][1] && board[i][2]==-1) {
            x=i;
            y=2; //board[i][2]
        } else if(board[i][1]==board[i][2] && board[i][0]==-1) {
            x=i;
            y=0; //board[i][0]
        } else if(board[i][0]==board[i][2] && board[i][1]==-1) {
            x=i;
            y=1; //board[i][1]
        } else if(board[0][0]==board[1][1] && board[2][2]==-1) {   //Diagonals
            x=2;
            y=2; //board[2][2]
        } else if(board[1][1]==board[2][2] && board[0][0]==-1) {
            x=0;
            y=0; //board[0][0]
        } else if(board[0][0]==board[2][2] && board[1][1]==-1) {
            x=1;
            y=1; //board[1][1]
        } else if(board[0][2]==board[1][1] && board[2][0]==-1) {
            x=2;
            y=0; //board[2][0]
        } else if(board[1][1]==board[2][0] && board[0][2]==-1) {
            x=0;
            y=2; //board[0][2]
        } else if(board[0][2]==board[2][0] && board[1][1]==-1) {
            x=1;
            y=1; //board[1][1]
        }
    }

    if(x!=-1 && y!=-1) { //Returns true if there are 2 in a row
        xglobal=x;
        yglobal=y;
        return true;
    } else {
        return false;
    }
}



void perfectplace()
{
    int x,y;
    if(turn()==0) {   //Places in a random corner if first
        x=(rand()%2)*2; //Picks either 0 or 2
        y=(rand()%2)*2;
        xstart=x;
        ystart=y;
    } else if(turn()==1) {
        if(xprev!=1 && yprev!=1) {      //If player takes corner, ai takes center
            x=1;
            y=1;
        } else if(xprev==1 && yprev==1) {       //If player takes center, ai takes a corner
            x=(rand()%2)*2; //Picks either 0 or 2
            y=(rand()%2)*2;
        } else {                          //If player takes edge, ai takes spot in either same row or col
            if(xprev==1) {
                x=rand()%3;
                if(x==xprev) {
                    do {
                        y=rand()%3;
                    } while(y==yprev);
                } else {
                    y=yprev;
                }
            } else {
                y=rand()%3;
                if(y==yprev) {
                    do {
                        x=rand()%3;
                    } while(x==xprev);
                } else {
                    x=xprev;
                }
            }
        }
    } else if(turn()==2) {
        if(xprev==1 && yprev==1) {   //If user places in middle, any open spot leads to tie
            do {
                x=rand()%3;
                y=rand()%3;
            } while(board[x][y]!=-1);
        } else if((xprev==1 ||yprev==1) && (xprev!=xstart && yprev!=ystart)) {   //Opposite edge
            if(xprev-xstart==2 || xprev-xstart==-2) {
                y=ystart;
                if(yprev+ystart==1)
                    x=2;
                else
                    x=0;
            } else {
                x=xstart;
                if(xprev+xstart==1)
                    y=2;
                else
                    y=0;
            }
        } else if((xprev==1 || yprev==1) && (xprev==xstart || yprev==ystart)) {  //Adjascent edge
            if(xprev==xstart) {
                do {
                    x=rand()%3;
                    y=rand()%3;
                } while(((ystart!=y) && (xstart==x)) || (x==1 && y==1));
            } else {
                do {
                    x=rand()%3;
                    y=rand()%3;
                } while(((xstart!=x) && (ystart==y)) || (x==1 && y==1));
            }
        } else if((xprev-xstart==2 || xprev-xstart==-2) && (yprev-ystart==2 || yprev-ystart==-2)) {  //Opposite Corner
            do {
                x=(rand()%2)*2;
                y=(rand()%2)*2;
            } while(board[x][y]!=-1);
        } else {     //Adjascent Corner
            if(xprev==xstart) {
                do {
                    x=rand()%3;
                    y=rand()%3;
                } while((ystart==y && xstart!=x) || (yprev==y && (yprev-y==2 || yprev-y==-2)));
            } else {
                do {
                    x=rand()%3;
                    y=rand()%3;
                } while((xstart==x && ystart!=y) || (xprev==x && (xprev-x==2 || xprev-x==-2)));
            }
        }
    } else {    //For turns 3+ If there are not 2 in a row, place in a random place unless the center is empty
        do {
            x=rand()%3;
            y=rand()%3;
        } while(board[x][y]!=-1);
        if(board[1][1]==-1) {
            x=1;
            y=1;
        }
        xglobal=x;
        yglobal=y;
        tworow();
    }
}

void monitorout()
{
    for(int i = 0; i < 3; i++) {
        for(int j = 0; j < 3; j++) {
            printf("%d ", board[i][j]);
        }
        printf("\n");
    }
    printf("\n\n");
}




void playerpc(int chip)
{
    int x,y;
    do {
        printf("Enter x coordinate\n");
        scanf("%d",&x);
        printf("Enter y coordinate\n");
        scanf("%d",&y);
    } while(board[x][y]!=-1);
    board[x][y]=chip;
    xprev=x;
    yprev=y;
    monitorout();
}




void placechip(int x,int y)
{
    drop=.8;        //Base position
    twist=.75;
    //Roll to correct x
    if(x!=0) {
        m.speed(-.4);
        wait(.25);
        if(x==2)
            wait(.15);
    }
    m.speed(0.0);
    //Twist to correct y
    if(y==0)
        twist=1.0;
    else if(y==1)
        twist=.75;
    else
        twist=.5;
    wait(.25);
    //Drop a Chip
    drop=.5;
    wait(.1);
    drop=.8;
    wait(.25);
    twist=.75;
    //Roll back to origin
    if(x!=0) {
        m.speed(.5);
        wait(.25);
        if(x==2)
            wait(.15);
    }
    m.speed(0.0);
    wait(5);
}