Lego EV3 Project - Software

While I was mostly responsible for the mechanical aspects of the project, I wrote the code that allowed moves to be entered into the EV3.

Some components of the software that were were originally planning on implementing weren't implemented due to some significant platform limitations, such as file transfer between a PC and the EV3 brick.

Let me explain. The checkers "AI" that we wrote was very primitive, but it was capable of generating moves based on what it thought was optimal, with some scoring mechanisms. This was written in C as we had hoped to port it over to the EV3, which was running RobotC.

However, should the EV3 be unable to run the code (spoiler alert, declaring an 8 by 8 array in RobotC causes a memory allocation error), we had hoped to run the program on a computer, generate files of the moves, and then read the files into the EV3, where the moves would be then executed.

File transfer using the EV3 and RobotC meant very finicky (for lack of a better word) use of the RobotC IDE to transfer files to the EV3.

This part of the project was then never properly realised, but the code written to enter moves in had already been written in case something like this occurred.

Here's a demonstration of an earlier version:


The program generates an 8 by 8 grid to represent the board, and then highlights squares - this was achieved by filling a region inside the grid. Pressing the buttons on the EV3 moved the square that was highlighted by erasing the filled region, and then filling in the next region.

Below is the code for how this was achieved. The vast majority of the code was written by me, with some tuning to variables and the X-Y coordinates done by my partners. Some code that was in the overall program has been replaced as it wasn't my work.


//Graphics
#define PATRICK_SQUARE_WIDTH 13
#define GRID_SPACE 15

// Conversion functions
int XtoPx(int x) {
    const int XSHIFT = 29;
    return x * GRID_SPACE + XSHIFT;
}

int YtoPx(int y) {
    const int YSHIFT = 1;
    return y * GRID_SPACE + YSHIFT;
}

void waitForPress() // debugging function {
    while(!getButtonPress(buttonAny))
    {}
    while(getButtonPress(buttonAny))
    {}
}

// EV3 Screen Functions
void drawGrid(string message) {
    const int LINEX0 = 43, LINEY0 = 15, GRIDX1 = 28, GRIDY1 = 120, GRIDX2 = 148, GRIDY2 = 0;
    eraseDisplay();
    displayString(0, "%s", message);
    drawRect(GRIDX1,GRIDY1,GRIDX2,GRIDY2);
    for (int lines = 0; lines < 7; lines++)
    {
        int x_pos = LINEX0 + (GRID_SPACE * lines);
        drawLine(x_pos, GRIDY1, x_pos, GRIDY2);
        int y_pos = LINEY0 + (GRID_SPACE * lines);
        drawLine(GRIDX1, y_pos, GRIDX2, y_pos);
    }
}

void selectPoint(int & X, int & Y) {
    fillRect(XtoPx(X), YtoPx(Y), XtoPx(X) + PATRICK_SQUARE_WIDTH, YtoPx(Y) + PATRICK_SQUARE_WIDTH);
    while (!getButtonPress(buttonAny))
    {}
    if (!getButtonPress(buttonEnter))
    {
        do
        {
            eraseRect(XtoPx(X), YtoPx(Y), XtoPx(X) + PATRICK_SQUARE_WIDTH, YtoPx(Y) + PATRICK_SQUARE_WIDTH);
            if (getButtonPress(buttonRight) && X < 7)     X++;
            else if (getButtonPress(buttonLeft) && X > 0)                 X--;

            else if (getButtonPress(buttonUp) && Y < 7)
Y++;
            else if (getButtonPress(buttonDown) && Y > 0)
Y--;
            while (getButtonPress(buttonAny))
            {}
            fillRect(XtoPx(X), YtoPx(Y), XtoPx(X) + PATRICK_SQUARE_WIDTH, YtoPx(Y) + PATRICK_SQUARE_WIDTH);
            while (!getButtonPress(buttonAny))
            {}
} while (!getButtonPress(buttonEnter));
    }
    while (getButtonPress(buttonEnter))
    {}
}

void confirmSelect(int selectX, int selectY, int moveX, int moveY, bool & selectedPiece, bool moving) {
    eraseDisplay();

    displayCenteredBigTextLine(2, "Are you sure?");
    displayCenteredTextLine(5, "Left = No, Right = Yes");
    while (!getButtonPress(buttonLeft) && !getButtonPress(buttonRight))
    {}
    if (getButtonPress(buttonRight))
selectedPiece = true;
    while (getButtonPress(buttonAny))
    {}
}

void playerMove(int & x1, int & y1, int & x2, int & y2) {
    int selectX = 0, selectY = 0, moveX = 0, moveY = 0;
    bool selectedPiece = false, selectedMove = false;
    string message = "Pick piece";
    while (!selectedPiece)
    {
eraseDisplay();
drawGrid(message);
selectPoint(selectX, selectY);
confirmSelect(selectX, selectY, moveX, moveY, selectedPiece, false);
    }
    message = "Point to move";
    while (!selectedMove)
    {
drawGrid(message);
selectPoint(moveX, moveY);
confirmSelect(selectX, selectY, moveX, moveY, selectedMove, true);
    }
    x1 = selectX + 1;
    y1 = selectY + 1;
    x2 = moveX + 1;
    y2 = moveY + 1;
}



Popular posts from this blog

Creating a Messenger Bot: Part 1

Java - Snowflake Animation