Hardware components | ||||||
![]() |
| × | 1 | |||
| × | 1 | ||||
Software apps and online services | ||||||
![]() |
|
A simple "Mastermind" clone for the Arduino Uno with 3.5" tft display.
With a random generator created by David Pankhurst
In the Arduino ide, you must install Adafruit_gfx, McuFriend_kbv and the TouchScreen_kbv library.
To do it, download the zip file TouchScreen_kbv (see below) and the code file. Open the Arduino ide, click on sketch->include library->add zip library and select the downloaded lib. Then press Ctrl+Shift+I. Type the name of the also needed library in the search bar and install the libs. Now open the downloaded code file and upload it to your Uno. Thats all, have fun!
#include <Adafruit_GFX.h> // Core graphics library
#include <TouchScreen_kbv.h>
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
#define TFT_BROWN 0x2060
#define TFT_MIDDLEBROWN 0x0820
#define TFT_DARKBROWN 0x1820
#define YP A2 // must be an analog pin, use "An" notation!
#define XM A3 // must be an analog pin, use "An" notation!
#define YM 8 // can be a digital pin
#define XP 9 // can be a digital pin
#define TS_MINX 130
#define TS_MAXX 905
#define TS_MINY 75
#define TS_MAXY 930
#define MINPRESSURE 20
Adafruit_GFX_Button buttons[6];
uint16_t buttoncolors[8] = {TFT_DARKGREEN, TFT_YELLOW, TFT_RED, TFT_PINK, TFT_GREEN, TFT_PURPLE, TFT_BLUE, TFT_DARKBROWN};
TouchScreen_kbv ts = TouchScreen_kbv(XP, YP, XM, YM, 300);
TSPoint_kbv p;
uint8_t lop, lop2, lop3, row, colorRight, allRight, color[4], rndColor[4], rndOld[4];
uint16_t result[5];
bool win = false;
void setup() {
tft.reset();
tft.begin(tft.readID());
tft.setRotation(0);
unsigned long seed = seedOut(31);
randomSeed(seed);
}
void loop() {
gameStart();
delButtColor();
do {
readTouch();
moveCheck();
} while (!win);
}
void readTouch() {
p = ts.getPoint();
p.x = p.x + p.y;
p.y = p.x - p.y;
p.x = p.x - p.y;
p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
p.y = tft.height() - (map(p.y, TS_MINY, TS_MAXY, tft.height(), 0));
}
void moveCheck() {
if ((buttons[5].contains(p.x, p.y)) && p.z > MINPRESSURE) {
loop();
}
if ((buttons[4].contains(p.x, p.y)) && p.z > MINPRESSURE){
tft.fillRect(230, 160, 80, 28, TFT_DARKBROWN);
if(color[0] == 7 || color[1] == 7 || color[2] == 7 || color[3] == 7){
tft.setTextSize(2);
tft.setCursor(240, 160);
tft.setTextColor(TFT_RED);
tft.print("Error");
tft.setTextSize(1);
tft.setCursor(232, 180);
tft.setTextColor(TFT_WHITE);
tft.print("Enter a code!");
}
else {
checkMove();
if (!win) {
row += 1;
if (row != 12) {
tft.setTextSize(2);
tft.setCursor(3, 455 - (row - 1) * 35);
tft.setTextColor(TFT_DARKBROWN);
tft.print(">");
tft.setCursor(3, 455 - row * 35);
tft.setTextColor(TFT_WHITE);
tft.print(">");
delButtColor();
}
if (row == 12)
{
tft.setCursor(220, 160);
tft.setTextColor(TFT_WHITE);
tft.print("YOU LOSE");
gameEnd();
}
}
if (win) {
tft.setCursor(225, 160);
tft.setTextColor(TFT_WHITE);
tft.print("YOU WIN");
gameEnd();
}
}
}
for (lop3 = 0; lop3 < 4; lop3++) {
if ((buttons[lop3].contains(p.x, p.y)) && p.z > MINPRESSURE) {
color[lop3] += 1;
if (color[lop3] > 6) color[lop3] = 1;
creatButton();
}
} delay(150);
}
void gameEnd() {
tft.setCursor(230, 180);
tft.setTextSize(1);
tft.print("The code was");
for (lop = 0; lop < 4; lop++) {
tft.fillCircle(234 + lop * 24, 205, 10, buttoncolors[rndColor[lop]]);
}
tft.setCursor(230, 260);
tft.print("Touch screen");
tft.setCursor(234, 270);
tft.print("to continue");
do{
delay(250);
readTouch();
}while(p.z<MINPRESSURE);
loop();
}
void delButtColor() {
for (lop3 = 0; lop3 < 4; lop3++) {
color[lop3] = 7;
creatButton();
}
}
void checkMove() {
allRight = 0;
colorRight = 0;
for (lop = 0; lop < 4; lop++) {
rndOld[lop] = rndColor[lop];
if (color[lop] == rndColor[lop]) {
color[lop] = -1;
rndOld[lop] = 0;
allRight += 1;
}
}
for (lop = 0; lop < 4; lop++) {
for (lop2 = 0; lop2 < 4; lop2++) {
if (color[lop] == rndOld[lop2])
{
color[lop] = -1;
rndOld[lop2] = 0;
colorRight += 1;
}
}
}
lop = 1;
lop2 = allRight;
do {
if (lop2 > 0) {
result[lop] = TFT_BLACK;
lop2 -= 1;
lop += 1;
}
} while (lop2 > 0);
do {
if (colorRight > 0) {
result[lop] = TFT_WHITE;
colorRight -= 1;
lop += 1;
}
} while (colorRight > 0);
for (lop2 = lop; lop2 < 5; lop2++) {
result[lop2] = TFT_MIDDLEBROWN;
}
tft.fillCircle(192, 453 - row * 35, 5, result[1]);
tft.fillCircle(206, 453 - row * 35, 5, result[2]);
tft.fillCircle(192, 468 - row * 35, 5, result[3]);
tft.fillCircle(206, 468 - row * 35, 5, result[4]);
if (allRight == 4) win = true;
}
void creatButton() {
buttons[lop3].initButton(&tft, 40 * lop3 + 41, 461 - (35 * row), 24, 24, TFT_DARKBROWN, buttoncolors[color[lop3]], TFT_DARKBROWN, "", 2);
buttons[lop3].drawButton();
}
void gameStart() {
win = false;
row = 0;
for (lop = 0; lop < 4; lop++)
{
rndColor[lop] = random(1, 7);
}
tft.fillScreen(TFT_DARKBROWN);
tft.setTextSize(4);
tft.setCursor(43, 15);
tft.setTextColor(TFT_BROWN);
tft.print("SuPErBrAIn");
tft.setCursor(40, 12);
tft.setTextColor(TFT_BLACK);
tft.print("SuPErBrAIn");
tft.fillRect(182, 61, 36, 416, TFT_MIDDLEBROWN);
for (lop = 0; lop < 3; lop++) {
if (lop == 1) {
tft.drawFastVLine(23 - lop, 57, 424, TFT_DARKBROWN);
tft.drawFastVLine(218 - lop, 57, 424, TFT_DARKBROWN);
}
else {
tft.drawFastVLine(23 - lop, 57, 424, TFT_BROWN);
tft.drawFastVLine(218 - lop, 57, 424, TFT_BROWN);
}
}
for (lop = 0; lop < 13; lop++) {
for (lop2 = 0; lop2 < 3; lop2++) {
if (lop2 == 1) tft.drawFastHLine(22, 35 * lop + 57 + lop2, 195, TFT_DARKBROWN);
else tft.drawFastHLine(23, 35 * lop + 57 + lop2, 193, TFT_BROWN);
}
}
for (lop3 = 0; lop3 < 4; lop3++) {
for (lop2 = 0; lop2 < 12; lop2++) {
for (lop = 0; lop < 3; lop++) {
if (lop == 1) {
tft.drawFastVLine(lop3 * 40 + 60 - lop, lop2 * 35 + 58, 36, TFT_DARKBROWN);
}
else {
tft.drawFastVLine(lop3 * 40 + 60 - lop, lop2 * 35 + 60, 33, TFT_BROWN);
}
}
}
}
tft.setTextSize(2);
tft.setCursor(3, 455);
tft.setTextColor(TFT_WHITE);
tft.print(">");
buttons[4].initButton(&tft, 268, 450, 80, 40, TFT_WHITE, buttoncolors[0], TFT_WHITE, "Enter", 2);
buttons[4].drawButton();
buttons[5].initButton(&tft, 268, 400, 80, 40, TFT_WHITE, buttoncolors[0], TFT_WHITE, "Reset", 2);
buttons[5].drawButton();
}
unsigned int bitOut(void)
{
static uint8_t firstTime = 1, prev = 0;
unsigned long bit1 = 0, bit0 = 0, x = 0, port = 5, limit = 99;
if (firstTime)
{
firstTime = 0;
prev = analogRead(port);
}
while (limit--)
{
x = analogRead(port);
bit1 = (prev != x ? 1 : 0);
prev = x;
x = analogRead(port);
bit0 = (prev != x ? 1 : 0);
prev = x;
if (bit1 != bit0)
break;
}
return bit1;
}
unsigned long seedOut(unsigned int noOfBits)
{
// return value with 'noOfBits' random bits set
unsigned long seed = 0;
for (int i = 0; i < noOfBits; ++i)
seed = (seed << 1) | bitOut();
return seed;
}
Comments
Please log in or sign up to comment.