#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTime>
#include <QTimer>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
QTimer *timer;
struct segm
{
int pos_x;
int pos_y;
int clr;
};
int table_row;
int table_col;
int pole[30][50];
QList<segm> zmeyka;
void make_zmeyka();
void print_zmeyka();
bool move_zmeyka(int);
private:
Ui::Widget *ui;
public slots:
void press_pbtn_01();
void onTimer();
};
#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// инициализация ГСЧ
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
timer = new QTimer();
table_row = ui->tableWidget->rowCount(); // 30
table_col = ui->tableWidget->columnCount(); // 50
for(int row = 0; row < table_row; row++)
for(int col = 0; col < table_col; col++)
{
pole[row][col] = 0;
QTableWidgetItem *it = new QTableWidgetItem;
it->setTextAlignment(Qt::AlignCenter);
ui->tableWidget->setItem(row, col, it);
}
// лабиринт
for(int i = 0; i < 3; i++)
for(int j = 5; j < 15; j++)
{
pole[j][i+10] = 1;
pole[j+10][i+10] = 1;
ui->tableWidget->item(j, i+10)->setBackgroundColor(Qt::gray);
ui->tableWidget->item(j+10, i+10)->setBackgroundColor(Qt::gray);
pole[j][i+37] = 1;
pole[j+10][i+37] = 1;
ui->tableWidget->item(j, i+37)->setBackgroundColor(Qt::gray);
ui->tableWidget->item(j+10, i+37)->setBackgroundColor(Qt::gray);
}
make_zmeyka();
print_zmeyka();
QObject::connect(ui->pbtn_01, SIGNAL(clicked()), this, SLOT(press_pbtn_01()));
connect(timer,SIGNAL(timeout()),this,SLOT(onTimer()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::press_pbtn_01()
{
timer->start(60);
}
bool Widget::move_zmeyka(int k)
{
QList<segm> sg;
int lng = zmeyka.length();
for(int i = 0; i < lng; i++)
{
sg << zmeyka.at(i);
}
int x = sg.at(0).pos_x;
int y = sg.at(0).pos_y;
if(k == 1) sg[0].pos_y--;
if(k == 2 )sg[0].pos_x--;
if(k == 3 )sg[0].pos_y++;
if(k == 4 )sg[0].pos_x++;
if((sg[0].pos_x < 0) ||
(sg[0].pos_y < 0) ||
(sg[0].pos_x > table_row-1) ||
(sg[0].pos_y > table_col-1))
return true;
// обход препятствий
if(pole[sg[0].pos_x][sg[0].pos_y]) return true;
sg[0].clr = 2;
zmeyka[0] = sg.at(0);
sg[0].pos_x = x;
sg[0].pos_y = y;
sg[0].clr = 1;
for(int i = 1; i < lng; i++)
{
sg[i] = zmeyka.at(i);
// последний сегмент белого цвета стирает след змейки
if(i == lng-1) sg[i-1].clr = 0;
zmeyka[i] = sg.at(i-1);
}
print_zmeyka();
return false;
}
void Widget::make_zmeyka()
{
segm sg;
// длина змейки
for(int i = 20; i < 30; i++)
{
sg.pos_x = 15;
sg.pos_y = i;
sg.clr = 1;
if(i == 20) sg.clr = 2;
if(i == 29) sg.clr = 0;
zmeyka << sg;
}
}
void Widget::print_zmeyka()
{
segm sg;
QColor sclr;
sg = zmeyka.at(zmeyka.size()-1);
ui->tableWidget->item(sg.pos_x, sg.pos_y)->setBackgroundColor(Qt::white);
for(int i = 0; i < zmeyka.size(); i++)
{
sg = zmeyka.at(i);
if(sg.clr == 0) sclr = Qt::white;
if(sg.clr == 1) sclr = Qt::green;
if(sg.clr == 2) sclr = Qt::red;
ui->tableWidget->item(sg.pos_x, sg.pos_y)->setBackgroundColor(sclr);
}
}
void Widget::onTimer()
{
static int cx = 0;
static int napr = 3;
static int oldnapr = 1;
if(!(cx % 7))
{
met_10:
napr = (qrand() % 4) + 1;
// запрет возврата в саму себя
if(napr == 2 && oldnapr == 4) goto met_10;
if(napr == 4 && oldnapr == 2) goto met_10;
if(napr == 1 && oldnapr == 3) goto met_10;
if(napr == 3 && oldnapr == 1) goto met_10;
}
// обход препятствий
if(move_zmeyka(napr)) goto met_10;
oldnapr = napr;
cx++;
}