Play battleship against another mbed over an ethernet internet connection

Dependencies:   4DGL-uLCD-SE EthernetInterface mbed-rtos mbed

Fork of Working_Get_Example_Ethernet by Ryan Quinn

main.cpp

Committer:
ndaniel7
Date:
2015-12-08
Revision:
18:ac354cf138dd
Parent:
17:46186f7da7eb

File content as of revision 18:ac354cf138dd:

#include "mbed.h"
#include "EthernetInterface.h"
#include <string>
#include "uLCD_4DGL.h"

Serial pc(USBTX,USBRX);

extern "C" void mbed_mac_address(char * mac) {
 
// define your own MAC Address ba:d7:05:47:1f:c6
  mac[0] = 0xba;  
  mac[1] = 0xd7;  
  mac[2] = 0x05;  
  mac[3] = 0x47;  
  mac[4] = 0x1f;  
  mac[5] = 0xc6;           
  
};

//int main() {
//    pc.baud(9600);
//    pc.printf("Running\n");
//    EthernetInterface eth;
//    eth.init(); //Use DHCP
//    wait(15);
//    eth.connect();
//    wait(15);
//    pc.printf("MAC is %s\n", eth.getMACAddress());
//    pc.printf("IP Address is %s\n", eth.getIPAddress());
//    
//    TCPSocketConnection sock;
//    sock.connect("192.184.82.3", 5000);
//    
//    char http_cmd[300] = "GET /create_board?playerNum=1&gameNum=144&board=1111000000000000000000000000000000000000000000000000000000000000 HTTP/1.0\n\n";
//    sock.send_all(http_cmd, sizeof(http_cmd)-1);
//    
//    //Instead of printing here, do what you did before to convert the string, and just append buffer to a string (below the break),
//    //    replacing pc.printf
//    //Then we can do string find to snipe the values we want (have to do math to grab the right amount)
//    //Implemented example here, testStr now holds the received text (so you can search it)
//    string testStr = "";
//    char buffer[600];
//    int ret;
//    while (true) {
//        ret = sock.receive(buffer, sizeof(buffer)-1);
//        if (ret <= 0)
//            break;
//        buffer[ret] = '\0';
//        pc.printf("Received %d chars from server:\n%s\n", ret, buffer);
//        string conv(buffer);
//        testStr = testStr + conv;
//    }
//    pc.printf("Stringified %s\n", testStr);
//    sock.close();
//    wait(0.2);
//    sock.connect("192.184.82.3", 5000);
//    wait(0.2);
//    strcpy(http_cmd, "GET /create_board?playerNum=2&gameNum=144&board=1111000000000000000000000000000000000000000000000000000000000000 HTTP/1.0\n\n");
//    pc.printf("Command is %s", http_cmd);
//    sock.send_all(http_cmd, sizeof(http_cmd)-1);
//    
//    while (true) {
//        ret = sock.receive(buffer, sizeof(buffer)-1);
//        if (ret <= 0)
//            break;
//        buffer[ret] = '\0';
//        pc.printf("Received %d chars from server:\n%s\n", ret, buffer);
//    }
//    
//    sock.close();
//    wait(0.2);
//    sock.connect("192.184.82.3", 5000);
//    wait(0.2);
//    strcpy(http_cmd, "GET /polling?gameNum=144&playerNum=1 HTTP/1.0\n\n");
//    pc.printf("Command is %s", http_cmd);
//    sock.send_all(http_cmd, sizeof(http_cmd)-1);
//    
//    while (true) {
//        ret = sock.receive(buffer, sizeof(buffer)-1);
//        if (ret <= 0)
//            break;
//        buffer[ret] = '\0';
//        pc.printf("Received %d chars from server:\n%s\n", ret, buffer);
//    }
//      
//    sock.close();
//    wait(0.2);
//    sock.connect("192.184.82.3", 5000);
//    wait(0.2);
//    strcpy(http_cmd, "GET /fire?playerNum=1&gameNum=144&x=1&y=0 HTTP/1.0\n\n");
//    pc.printf("Command is %s", http_cmd);
//    sock.send_all(http_cmd, sizeof(http_cmd)-1);
//    
//    while (true) {
//        ret = sock.receive(buffer, sizeof(buffer)-1);
//        if (ret <= 0)
//            break;
//        buffer[ret] = '\0';
//        pc.printf("Received %d chars from server:\n%s\n", ret, buffer);
//    }
//    
//    sock.close();
//    eth.disconnect();
//    
//    while(1) {}
//}

uLCD_4DGL lcd(p28,p27,p29);
DigitalOut myled(LED1);

AnalogIn sliderh(p17);
AnalogIn sliderv(p19);
DigitalIn pb1(p21);
bool down = false;
string gameID = "";
string myBoard = "";
string targetBoard = "";
int size=7;//board square size in pixels
int cx=0,cy=0;//cursor position
int playerNum;

//If button is pressed, print only once
bool check_button() {
    if(pb1 == 0 && !down) {
        return true;
    }
    if(pb1 == 1) {
        down = false;
    }
    return false;
}

void emptyBoards() {
    myBoard="";
    targetBoard="";
    for (int i=0;i<64;i++) {
        myBoard+="0";
        targetBoard+="0";
    }
}

//0: nothing
//1: down
//2: up
//3: right
//4: down
//5: button press
int analogStick() {
    if(sliderh < 0.2) {
        return 1;
    }
    else if(sliderh > 0.8) {
        return 2;
    }
    else if(sliderv < 0.2) {
        return 3;
    }
    else if(sliderv > 0.8) {
        return 4;
    }
    else if (check_button()){
        return 5;
    }
    else
        return 0;
}

string playerMenu(){
    lcd.cls();
    wait(0.2);
    //lcd.printf("Player Select:");
    lcd.locate(3,0);
    lcd.printf("Host a Game");
    lcd.locate(3, 14);
    lcd.printf("Join a Game");
    while (1){
        if (analogStick()==2){
            return "1";
        }
        else if (analogStick()==1){
            return "2";
        }
    }
            
}

void selectMenu(){
    lcd.cls();
    wait(0.2);
    lcd.locate(1,0);
    lcd.printf("Current GameID:");
    int input;
    while (1){
        input = analogStick();
        if (input==5) {
            break;
        }
        else if (input==0) {
            lcd.locate(1,0);
            lcd.printf("Current GameID:  %s",gameID);
            continue;
        }
        char buf[10];
        sprintf(buf,"%d",input);
        gameID.append(buf);
        wait(0.3);
    }  
}

void drawTargetBoard(){
    int x=0;
    int y=0;
    string s;
    for (int i=0;i<64;i++) {
        x=7*(i%8);
        if (i%8==0 && i!=0) {
            y+=size;
        }
        s = targetBoard.at(i);
        if (s.compare("0")==0){ //water
            lcd.filled_rectangle(x,y,x+size-1,y+size-1,0x0000FF);
        }
        else if (s.compare("0")==1){ //unknown opponent ship
            lcd.filled_rectangle(x,y,x+size-1,y+size-1,0x0000FF);
        }
        else if (s.compare("0")==2){ //hit
            lcd.filled_rectangle(x,y,x+size-1,y+size-1,0xFF0000);
        } 
        else if (s.compare("0")==3){ //miss
            lcd.filled_rectangle(x,y,x+size-1,y+size-1,0xFFFFFF);
        }
    }
}

void drawMyBoard(){
    int x=0;
    int y=56+16;
    string s;
    for (int i=0;i<64;i++) {
        x=7*(i%8);
        if (i%8==0 && i!=0) {
            y+=size;
        }
        s = myBoard.at(i);
        if (s.compare("0")==0){ //water
            lcd.filled_rectangle(x,y,x+size-1,y+size-1,0x0000FF);
        }
        else if (s.compare("0")==1){ //my ship
            lcd.filled_rectangle(x,y,x+size-1,y+size-1,0x2F4F4F);
        }
        else if (s.compare("0")==2){ //hit
            lcd.filled_rectangle(x,y,x+size-1,y+size-1,0xFF0000);
        } 
        else if (s.compare("0")==3){ //miss
            lcd.filled_rectangle(x,y,x+size-1,y+size-1,0xFFFFFF);
        }
    }
}

void drawLegend(){
    int startX=64;
    int startY=16;
    int lSize=5;
    int dY=24;
    lcd.locate(11,2);
    lcd.printf("Water");
    lcd.filled_rectangle(startX,startY,startX+lSize,startY+lSize,0x0000FF);
    lcd.locate(11,5);
    lcd.printf("Ship");
    lcd.filled_rectangle(startX,startY+dY,startX+lSize,startY+dY+lSize,0x2F4F4F);
    lcd.locate(11,8);
    lcd.printf("Hit");
    lcd.filled_rectangle(startX,startY+2*dY,startX+lSize,startY+2*dY+lSize,0xFF0000);
    lcd.locate(11,11);
    lcd.printf("Miss");
    lcd.filled_rectangle(startX,startY+3*dY,startX+lSize,startY+3*dY+lSize,0xFFFFFF);
}

void drawBoards() {
    lcd.cls();
    //wait(0.2);
    drawTargetBoard();
    drawMyBoard();
    drawLegend();
}

void selectTarget(){//selected x,y coords are stored in global cx/cy coords
    drawBoards();
    lcd.filled_rectangle(cx*size,cy*size,cx*size+size-1,cy*size+size-1,0xFFFF00);
    int input;
    while (1) {
        input=analogStick();
        if (input==5) {
            return;
        }
        if (input==1) {//down
            if (cy<7) {
                cy++;
            }
        }
        if (input==2) {//up
            if (cy>0) {
                cy--;
            }
        }
        if (input==3) {//right
            if (cx<7) {
                cx++;
            }
        }
        if (input==4) {//left
            if (cx>0) {
                cx--;
            }
        }
        if (input!=0) {
            drawBoards();
            lcd.filled_rectangle(cx*size,cy*size,cx*size+size-1,cy*size+size-1,0xFFFF00);
        }
    }
}

void placeShip(int s){
    for (int i=0;i<s;i++) {
        drawBoards();
        lcd.filled_rectangle(cx*size,cy*size+72,cx*size+(size-1)*2,cy*size+72+size-1,0xFFFF00);
        int input;
        while (1) {
            input=analogStick();
            if (input==5) {
                break;
            }
            if (input==1) {//down
                if (cy<7) {
                    cy++;
                }
            }
            if (input==2) {//up
                if (cy>0) {
                    cy--;
                }
            }
            if (input==3) {//right
                if (cx<6) {
                    cx++;
                }
            }
            if (input==4) {//left
                if (cx>0) {
                    cx--;
                }
            }
            if (input!=0) {
                drawBoards();
                lcd.filled_rectangle(cx*size,cy*size+72,cx*size+(size-1)*2,cy*size+72+size-1,0xFFFF00);
            }
        }
        myBoard.replace(cy*8+cx,2,"11");
    }
}

int main() {
    pc.baud(9600);
    pc.printf("Running\n");
    EthernetInterface eth;
    eth.init(); //Use DHCP
    wait(15);
    eth.connect();
    wait(15);
    pc.printf("MAC is %s\n", eth.getMACAddress());
    pc.printf("IP Address is %s\n", eth.getIPAddress());
    TCPSocketConnection sock;
    char http_cmd[300];
    string cmdStr = "";
    string resultStr = "";
    char buffer[600];
    int ret;
    std::size_t found;

    emptyBoards();
    pb1.mode(PullUp);
    lcd.baudrate(3000000);
    lcd.cls();
    //lcd.printf("%d",analogStick());
    //lcd.printf("%d",playerMenu());
    string pm = playerMenu();
    wait(0.5);
    selectMenu();
    lcd.cls();
    placeShip(2);
    sock.connect("192.184.82.3", 5000);
    cmdStr = "GET /create_board?playerNum=";
    cmdStr += pm;
    cmdStr += "&gameNum=";
    cmdStr += gameID;
    cmdStr += "&board=";
    cmdStr += myBoard;
    cmdStr += " HTTP/1.0\n\n";
    strcpy(http_cmd, cmdStr.c_str());
    pc.printf(http_cmd);
    sock.send_all(http_cmd, sizeof(http_cmd)-1);
    
    //Instead of printing here, do what you did before to convert the string, and just append buffer to a string (below the break),
    //    replacing pc.printf
    //Then we can do string find to snipe the values we want (have to do math to grab the right amount)
    //Implemented example here, testStr now holds the received text (so you can search it)
    while (true) {
        ret = sock.receive(buffer, sizeof(buffer)-1);
        if (ret <= 0)
            break;
        buffer[ret] = '\0';
        string conv(buffer);
        resultStr = resultStr + conv;
    }
    sock.close();
    resultStr="";
    wait(0.2);//we have now setup and sent the board
    
    while (1){
        while (1){
            sock.connect("192.184.82.3", 5000);//start polling to wait for turn
            wait(0.2);
            cmdStr = "GET /polling?playerNum=";
            cmdStr += pm;
            cmdStr += "&gameNum=";
            cmdStr += gameID;
            cmdStr += " HTTP/1.0\n\n";
            strcpy(http_cmd, cmdStr.c_str());
            pc.printf("Command is %s", http_cmd);
            sock.send_all(http_cmd, sizeof(http_cmd)-1);
            resultStr = "";
            while (true) {
                ret = sock.receive(buffer, sizeof(buffer)-1);
                if (ret <= 0)
                    break;
                buffer[ret] = '\0';
                string conv(buffer);
                resultStr = resultStr + conv;
            }
            found = resultStr.find("You lose");
            pc.printf("%s",resultStr);
            if(found!=std::string::npos){
                wait(3);
                sock.close();
                wait(0.2);
                lcd.cls();
                drawTargetBoard();
                drawMyBoard();
                lcd.locate(12,5);
                lcd.printf("You");
                lcd.locate(12,9);
                lcd.printf("Lose!");
                return;
            }
            found = resultStr.find("Don't go");
            pc.printf("%s",resultStr);
            if(found==std::string::npos){
                wait(3);
                sock.close();
                wait(0.2);
                break;
            }
            sock.close();
            wait(2);
        }
        //Now your turn
//        if (myBoard.at(cy*8+cx)=='1') {
//            targetBoard.replace(cy*8+cx,1,"2");
//            myBoard.replace(cy*8+cx,1,"2");
//        }
//        else{
//             targetBoard.replace(cy*8+cx,1,"3");
//             myBoard.replace(cy*8+cx,1,"3");
//        }
        string tmp = "player";
        tmp += pm;
        tmp += "_board";
//        pc.printf("\nwe printing shit");
//        pc.printf("\ntmp: %s",tmp);
        found = resultStr.find(tmp);
        pc.printf("\nfound: %d",found);
        myBoard = resultStr.substr(found+17,64);
        wait(0.5);
//        pc.printf("\nmyBoard: %s",myBoard);
//        pc.printf("\nresultStr: %s",resultStr);
        tmp = "player";
        tmp += pm;
        tmp += "_board";
        if (pm.compare("1")==0)
            tmp += "_p2";
        else
            tmp += "_p1";
        found = resultStr.find(tmp);
        targetBoard = resultStr.substr(found+20,64);
        drawBoards();
        cx=0,cy=0;
        selectTarget();
        sock.connect("192.184.82.3", 5000);//start polling to wait for turn
        wait(0.2);
        cmdStr = "GET /fire?playerNum=";
        cmdStr += pm;
        cmdStr += "&gameNum=";
        cmdStr += gameID;
        cmdStr += "&x=";
        char buf[10];
        sprintf(buf,"%d",cx);
        cmdStr.append(buf); 
        cmdStr += "&y=";
        char buf2[10];
        sprintf(buf2,"%d",cy);
        cmdStr.append(buf2); 
        cmdStr += " HTTP/1.0\n\n";
        //strcpy(http_cmd, "GET /fire?playerNum=1&gameNum=144&x=1&y=0 HTTP/1.0\n\n");
        strcpy(http_cmd, cmdStr.c_str());
        pc.printf("Command is %s", http_cmd);
        sock.send_all(http_cmd, sizeof(http_cmd)-1);
        resultStr = "";
        while (true) {
            ret = sock.receive(buffer, sizeof(buffer)-1);
            if (ret <= 0)
                break;
            buffer[ret] = '\0';
            string conv(buffer);
            resultStr = resultStr + conv;
        }
        found = resultStr.find("You win");
        pc.printf("%s",resultStr);
        if(found!=std::string::npos){
            wait(1.5);
            sock.close();
            wait(0.2);
            lcd.cls();
            drawTargetBoard();
            drawMyBoard();
            lcd.locate(12,5);
            lcd.printf("You");
            lcd.locate(12,9);
            lcd.printf("Win!");
            return;
        }
        sock.close();
        wait(0.5);
    }
    
}