swag

Dependencies:   Motor Servo mbed_tictactoe

main.cpp

Committer:
mattsims12
Date:
2015-10-20
Revision:
2:cbc3ef689c91
Parent:
1:c9f7302eac4f
Child:
3:317e06586628

File content as of revision 2:cbc3ef689c91:

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

DigitalOut test(LED1);
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 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");
    int 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
    while(winner()==-1) {
        if(playerchip==1) {
            player(playerchip);
            if(winner()!=-1)
                break;
            ai(aichip,difficulty);
            if(winner()!=-1)
                break;
        } else {
            ai(aichip,difficulty);
            if(winner()!=-1)
                break;
            player(playerchip);
            if(winner()!=-1)
                break;
        }
    }

    //Operates LED's based on winner
    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,y;
    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;
    placechip(x,y);
}




//Counts filled spaces to determine how many turns have passed
int turn()
{
    int turn=9;
    for(int i=1; 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) {    //Sometimes doesn't notice two in a row
                    x=xglobal;
                    y=yglobal;
                } else if(difficulty==3) {    //Always notices 2 in a row
                    x=xglobal;
                    y=yglobal;
                }
            }
        } else {
            perfectplace();
            x=xglobal;
            y=yglobal;
        }
        board[x][y]=chip;
        placechip(x,y);
    }
}



bool tworow()
{
    //Vertical and horizontals
    for(int i=0; i<=2; i++) {
        if(board[0][i]==board[1][i] && board[2][i]==-1) {
            xglobal=2;
            yglobal=i; //board[2][i]
        }
        if(board[1][i]==board[2][i] && board[0][i]==-1) {
            xglobal=0;
            yglobal=i; //board[0][i]
        }
        if(board[0][i]==board[2][i] && board[1][i]==-1) {
            xglobal=1;
            yglobal=i; //board[1][i]
        }

        if(board[i][0]==board[i][1] && board[i][2]==-1) {
            xglobal=i;
            yglobal=2; //board[i][2]
        }
        if(board[i][1]==board[i][2] && board[i][0]==-1) {
            xglobal=i;
            yglobal=0; //board[i][0]
        }
        if(board[i][0]==board[i][2] && board[i][1]==-1) {
            xglobal=i;
            yglobal=1; //board[i][1]
        }
    }
    //Diagonal Components
    if(board[0][0]==board[1][1] && board[2][2]==-1) {
        xglobal=2;
        yglobal=2; //board[2][2]
    }
    if(board[1][1]==board[2][2] && board[0][0]==-1) {
        xglobal=0;
        yglobal=0; //board[0][0]
    }
    if(board[0][0]==board[2][2] && board[1][1]==-1) {
        xglobal=1;
        yglobal=1; //board[1][1]
    }

    if(board[0][2]==board[1][1] && board[2][0]==-1) {
        xglobal=2;
        yglobal=0; //board[2][0]
    }
    if(board[1][1]==board[2][0] && board[0][2]==-1) {
        xglobal=0;
        yglobal=2; //board[0][2]
    }
    if(board[0][2]==board[2][0] && board[1][1]==-1) {
        xglobal=1;
        yglobal=1; //board[1][1]
    }
    if(xglobal==-1 && yglobal==-1)  //Returns true if there are 2 in a row
        return false;
    else
        return true;
}



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




void placechip(int x,int y)
{
    drop=.8;
    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);
}