I have written a program to solve uva's minesweeper problem (10189) in C++.
I have written the code, and it seems to work correctly on my machine. Unfortunately my submission seems to be giving me run-time error (uva does not mention the error message or reason in such cases). I am pasting the code here:
using namespace std;
void nullCheck(void *ptr)
{
exit(0);
}
typedef unsigned int uint;
class Field
{
public:
vector <vector<uint> > nghBombCnt; //neighbourBombCount
vector <vector<bool> > isBomb;
uint width;
uint height;
public:
Field(uint w, uint h)
{
}
Field() { }
~Field()
{
}
};
int main(void)
{
vector<Field> fieldList;
do
{
Field curField;
uint width, height;
scanf("%u %u", &height, &width);
curField.width = width;
curField.height = height;
for (uint rowCtr = 0; rowCtr < curField.height; rowCtr++)
{
vector<bool> curBombRow;
for (uint colCtr = 0; colCtr < curField.width; colCtr++)
{
char curSymb;
scanf("%1s", &curSymb);
switch (curSymb)
{
case '.':
curBombRow.push_back(false); break;
case '*':
curBombRow.push_back(true); break;
default: break;
}
}
curField.isBomb.push_back(curBombRow);
}
if (!(curField.width == 0 && curField.height == 0))
fieldList.push_back(curField);
else
break;
} while (1);
for (uint fieldCtr = 0; fieldCtr < fieldList.size(); fieldCtr++)
{
Field curField = fieldList.at(fieldCtr);
for (uint rowCtr = 0; rowCtr < curField.height; rowCtr++)
{
vector<uint> curRow;
for (uint colCtr = 0; colCtr < curField.width; colCtr++)
{
uint bombCnt = 0;
if (curField.isBomb[rowCtr][colCtr])
{
curRow.push_back(0);
continue;
}
if (colCtr != 0 && curField.isBomb[rowCtr][colCtr - 1])
bombCnt++; //east
if (rowCtr != 0 && curField.isBomb[rowCtr - 1][colCtr])
bombCnt++; //north
if (rowCtr != curField.height - 1
&& curField.isBomb[rowCtr + 1][colCtr])
bombCnt++; //south
if (colCtr != curField.width - 1
&& curField.isBomb[rowCtr][colCtr + 1])
bombCnt++; //west
if (colCtr != curField.width - 1 && rowCtr != 0
&& curField.isBomb[rowCtr -1][colCtr + 1])
bombCnt++; //north-east
if (colCtr != 0 && rowCtr != curField.height - 1
&& curField.isBomb[rowCtr + 1][colCtr - 1])
bombCnt++; // south-west
if (colCtr != curField.width - 1
&& rowCtr != curField.height - 1
&& curField.isBomb[rowCtr + 1][colCtr + 1])
bombCnt++; //south-east
if (colCtr != 0 && rowCtr != 0
&& curField.isBomb[rowCtr - 1][colCtr - 1])
bombCnt++; //north-west
curRow.push_back(bombCnt);
}
curField.nghBombCnt.push_back(curRow);
}
fieldList[fieldCtr] = curField;
}
for (uint fieldNo = 0; fieldNo < fieldList.size(); fieldNo++)
{
printf("Field #%u:\n", fieldNo + 1);
Field curField = fieldList.at(fieldNo);
for (uint rowCtr = 0; rowCtr < curField.height; rowCtr++)
{
for (uint colCtr = 0; colCtr < curField.width; colCtr++)
{
if (curField.isBomb[rowCtr][colCtr])
printf("*");
else
printf("%u", curField.nghBombCnt[rowCtr][colCtr]);
}
printf("\n");
}
printf("\n");
}
return 0;
}
Related
I am new to c++ and qt, but I want to learn. The essence of the problem: the application hangs when you click on the button, although before some edits worked adequately (rolling back edits did not help). As far as I understand it is because of the while loop, but nowhere can I find an answer on how to fix it.
The program itself, what I need to implement, is to write the interaction of predators and herbivores, for a start on a primitive level.
So, please help me with the problem of hanging the application.
Creating classes
class Grass
{...};
class Predator
{...};
class Herbivorous
{...};
Button click processing
void MainWindow::on_pushButton_clicked()
{
int kol_grass = ui->lineEdit_11->text().toInt(), kol_weeks = 0, t, t_x, t_y, kol_H = ui->lineEdit->text().toInt(), kol_P = ui->lineEdit_2->text().toInt(), k = 0, kk = 0;
list<Herbivorous> lst_H;
list<Predator> lst_P;
list<Grass> lst_G;
int kol_die_P_hungry = 0, kol_die_H_hungry = 0, kol_die_P_age = 0, kol_die_H_age = 0, eaten = 0;
int years = 0;
qsrand(QDateTime::currentMSecsSinceEpoch());
//resize dynamic lists
lst_H.resize(kol_H);
lst_P.resize(kol_P);
lst_G.resize(kol_grass);
//creating list iterators
list<Herbivorous>::iterator i = lst_H.begin();
list<Herbivorous>::iterator j = lst_H.begin();
list<Predator>::iterator ii = lst_P.begin();
list<Predator>::iterator jj = lst_P.begin();
list<Grass>::iterator grass_it = lst_G.begin();
//creating grass objects
for (; grass_it != lst_G.end(); grass_it++)
{
//...
}
grass_it = lst_G.begin();
//creating herbivore objects
for (; i != lst_H.end(); i++)
{
//...
}
//creating predator objects
for (; ii != lst_P.end(); ii++)
{
//...
}
i = lst_H.begin();
ii = lst_P.begin();
Then the same cycle
Apparently, the application hangs, when you click on the button. What am I doing wrong?
//as long as both animal species are alive, simulate life
while (lst_H.size() > 0 && lst_P.size() > 0)
{
//grass rendering
for (; grass_it != lst_G.end(); grass_it++)
{
if (grass_it->GetValue() != .0)
{
QTableWidgetItem * grass = new QTableWidgetItem();
grass->setBackground(Qt::green);
ui->tableWidget->setItem(grass_it->GetY(), grass_it->GetX(), grass);
}
}
grass_it = lst_G.begin();
//once a month grass replenishment
if (kol_weeks % 4 == 0)
{
grass_it = lst_G.begin();
for(; grass_it != lst_G.end(); grass_it++)
{
grass_it->Recovery();
}
grass_it = lst_G.begin();
}
//once a month check for starvation
if (kol_weeks % 4 == 0)
{
i = lst_H.begin();
for (; i != lst_H.end(); i++)
{
if (i->GetHungry() <= 0)
{
i->SetInLife(false);//смерть от голода
kol_die_H_hungry++;
}
else
{
i->SetAge(i->GetAge() + 1);//+1 год
}
}
i = lst_H.begin();
ii = lst_P.begin();
for (; ii != lst_P.end(); ii++)
{
if (ii->GetHungry() <= 0)
{
ii->SetInLife(false);//смерть от голода
kol_die_P_hungry++;
}
else
{
ii->SetAge(ii->GetAge() + 1);//+1 год
}
}
ii = lst_P.begin();
}
//once a year old age check
if (kol_weeks == 48)
{
i = lst_H.begin();
kol_weeks = 0;
years++;
for (; i != lst_H.end(); i++)
{
if (i->GetAge() >= ui->lineEdit_3->text().toInt())
{
i->SetInLife(false);//смерть от старости
kol_die_H_age++;
}
else
{
i->SetAge(i->GetAge() + 1);//+1 год
}
}
i = lst_H.begin();
ii = lst_P.begin();
for (; ii != lst_P.end(); ii++)
{
if ((ii->GetAge() >= ui->lineEdit_10->text().toInt()) || (ii->GetHungry() <= 0))
{
ii->SetInLife(false);//смерть от старости или от голода
kol_die_P_age++;
}
else
{
ii->SetAge(ii->GetAge() + 1);//+1 год
}
}
ii = lst_P.begin();
}
//movement of herbivores
for (; i != lst_H.end(); i++)
{
QTableWidgetItem * noherbivorous = new QTableWidgetItem();
noherbivorous->setBackground(Qt::black);
ui->tableWidget->setItem(i->GetY(), i->GetX(), noherbivorous);
if (i->GetInLife() == true)
{
i->Direction();
i->Hungry();
QTableWidgetItem * herbivorous = new QTableWidgetItem();
herbivorous->setBackground(Qt::white);
ui->tableWidget->setItem(i->GetY(), i->GetX(), herbivorous);
}
}
//moving predators
for (; ii != lst_P.end(); ii++)
{
QTableWidgetItem * nopredator = new QTableWidgetItem();
nopredator->setBackground(Qt::black);
ui->tableWidget->setItem(ii->GetY(), ii->GetX(), nopredator);
if (ii->GetInLife() == true)
{
ii->Direction();
ii->Hungry();
QTableWidgetItem * predator = new QTableWidgetItem();
predator->setBackground(Qt::red);
ui->tableWidget->setItem(ii->GetY(), ii->GetX(), predator);
}
}
lst_H.remove_if([] (Herbivorous a) {return (a.GetInLife() == false);});//the removal of dead
lst_P.remove_if([] (Predator a) {return (a.GetInLife() == false);});//the removal of dead
i = lst_H.begin();
j = lst_H.begin();
//death of parents and birth of children (herbivores)
for (; i != lst_H.end(); i++)
{
for (; j != lst_H.end(); j++)
{
if ((i->GetNumber() != j->GetNumber()) && (i->GetInLife() == true) && (j->GetInLife() == true) && (i->GetAge() >= i->GetMin_Rep()) && (i->GetAge() <= i->GetMax_Rep()) && (j->GetAge() >= j->GetMin_Rep()) && (j->GetAge() <= j->GetMax_Rep()))
{
t_x = i->GetX() - j->GetX();
t_y = i->GetY() - j->GetY();
if (((t_x == 1) || (t_x == -1) || (t_x == 0)) && ((t_y == 1) || (t_y == -1) || (t_y == 0)))
{
i->SetInLife(false);
j->SetInLife(false);
//creating children
t = qrand() % (4 + 1);//от 0 до 4 детей
for (int u = 0; u < t; u++)
{
Herbivorous child;
child.SetInLife(true);
child.SetX(qrand() % (234 + 1));//рандом
child.SetY(qrand() % (144 + 1));//рандом
child.SetAge(1);
child.SetFood(ui->lineEdit_6->text().toDouble());
child.SetNumber(kk);
child.SetMax_Rep(ui->lineEdit_4->text().toInt());
child.SetMin_Rep(ui->lineEdit_5->text().toInt());
k++;
lst_H.push_back(child);
}
}
}
}
j = lst_H.begin();
}
ii = lst_P.begin();
jj = lst_P.begin();
//death of parents and birth of children (predators)
for (; ii != lst_P.end(); ii++)
{
for (; jj != lst_P.end(); jj++)
{
if ((ii->GetNumber() != jj->GetNumber()) && (ii->GetInLife() == true) && (jj->GetInLife() == true) && (ii->GetAge() >= ii->GetMin_Rep()) && (ii->GetAge() <= ii->GetMax_Rep()) && (jj->GetAge() >= jj->GetMin_Rep()) && (jj->GetAge() <= jj->GetMax_Rep()))
{
t_x = ii->GetX() - jj->GetX();
t_y = ii->GetY() - jj->GetY();
if (((t_x == 1) || (t_x == -1) || (t_x == 0)) && ((t_y == 1) || (t_y == -1) || (t_y == 0)))
{
ii->SetInLife(false);
jj->SetInLife(false);
//creating children
t = qrand() % (4 + 1);//от 0 до 4 детей
for (int u = 0; u < t; u++)
{
Predator child;
child.SetInLife(true);
child.SetX(qrand() % (234 + 1));//рандом
child.SetY(qrand() % (144 + 1));//рандом
child.SetAge(1);
child.SetFood(ui->lineEdit_8->text().toDouble());
child.SetNumber(k);
child.SetMax_Rep(ui->lineEdit_9->text().toInt());
child.SetMin_Rep(ui->lineEdit_7->text().toInt());
kk++;
lst_P.push_back(child);
}
}
}
}
jj = lst_P.begin();
}
ii = lst_P.begin();
j = lst_H.begin();
//hunting of predators on herbivores
for (; ii != lst_P.end(); ii++)
{
if (ii->GetHungry() < 1)
{
for (; j != lst_H.end(); j++)
{
if ((ii->GetInLife() == true) && (j->GetInLife() == true))
{
t_x = ii->GetX() - j->GetX();
t_y = ii->GetY() - j->GetY();
if (((t_x == 1) || (t_x == -1) || (t_x == 0)) && ((t_y == 1) || (t_y == -1) || (t_y == 0)))
{
j->SetInLife(false);
ii->SetHungry(ii->GetHungry() + 1);
eaten++;
}
}
}
}
j = lst_H.begin();
}
grass_it = lst_G.begin();
//hunting herbivores on the grass
for (; j != lst_H.end(); j++)
{
if (j->GetHungry() < 1)
{
for (; grass_it != lst_G.end(); grass_it++)
{
if ((grass_it->GetValue() > 0) && (j->GetInLife() == true) && (j->GetX() == grass_it->GetX()) && (j->GetY() == grass_it->GetY()))
{
if (grass_it->GetValue() > 0.5)
{
j->SetHungry(j->GetHungry() + 0.5);
grass_it->SetValue(grass_it->GetValue() - 0.5);
}
else
{
j->SetHungry(j->GetHungry() + grass_it->GetValue());
grass_it->SetValue(0);
}
}
}
}
j = lst_H.begin();
}
i = lst_H.begin();
ii = lst_P.begin();
grass_it = lst_G.begin();
//summary of interim results
ui->label_11->setText("The number of herbivores: " + QString::number(lst_H.size()));
...
QEventLoop loop;
QTimer::singleShot(100, &loop, SLOT(quit()));
loop.exec();
kol_weeks++;
}
}```
I'm working in the watershed algortih in C++. I have implemented a source that i've found but i didn't get the expected results. I obtain:
[
But the result should be this:
[
I have charge the image .bmp into a matrix an then i obtain the Gradient of the image using the Sobel operator.
My wathershed algorith now is:
void Watershed() {
stack<punto> s;
punto p, neighbour;
C_Matrix prueba3 (Gradiente.FirstRow(), Gradiente.LastRow(), Gradiente.FirstCol(), Gradiente.LastCol(), -1);
int auxU, auxV, Eaux, L=1;
for (double g = Gradiente.Min(); g <= Gradiente.Max(); g++) {
for (int i = Gradiente.FirstRow(); i <= Gradiente.LastRow(); i++) {
for (int j = Gradiente.FirstCol(); j <= Gradiente.LastCol(); j++) {
if (Gradiente(i, j) == g) {
p.Guarda(i, j);
s.push(p);
}
while (s.empty() == 0) {
p = s.top();
s.pop();
auxU = p.x;
auxV = p.y;
Eaux = -1;
// 8-connectivity
for (int i = 0; i < 8; i++) {
if (i == 0)
neighbour.Guarda(auxU - 1, auxV - 1);
else if (i == 1)
neighbour.Guarda(auxU, auxV - 1);
else if (i == 2)
neighbour.Guarda(auxU + 1, auxV - 1);
else if (i == 3)
neighbour.Guarda(auxU - 1, auxV);
else if (i == 4)
neighbour.Guarda(auxU + 1, auxV);
else if (i == 5)
neighbour.Guarda(auxU - 1, auxV + 1);
else if (i == 6)
neighbour.Guarda(auxU, auxV + 1);
else
neighbour.Guarda(auxU + 1, auxV + 1);
if (neighbour.x >= Gradiente.FirstRow() && neighbour.x <= Gradiente.LastRow()
&& neighbour.y >= Gradiente.FirstCol() && neighbour.y <= Gradiente.LastCol()) {
if (prueba3(neighbour.x, neighbour.y) > 0) {
if (Eaux == -1) {
Eaux = prueba3(neighbour.x, neighbour.y);
}
else if (prueba3(neighbour.x, neighbour.y) != Eaux)
Eaux = 0;
}
}
}
if (auxU >= Gradiente.FirstRow() && auxU <= Gradiente.LastRow()
&& auxV >= Gradiente.FirstCol() && auxV <= Gradiente.LastCol()) {
if (Eaux >= 0) {
prueba3(auxU, auxV) = Eaux;
}
else {
prueba3(auxU, auxV) = L;
L++;
}
}
else {
C_Print("Se sale");
C_PrintNum("AuxU", auxU);
C_PrintNum("AuxV", auxV);
}
}
}
}
}
C_PrintNum("L = ", L);
double max = prueba3.Max();
if (max > 255.0) {
prueba3.Stretch(0, 255);
}
aux = C_Image(prueba3);
}
I don't know where is the fail, maybe my source has mistakes.
I took some days to code 2048 game. And now I made most of the functions but one, testing whether the game is over. To code this game, my idea is to merge the same numbers first with the function up(down, left or right)_merge and make all the numbers go to the arrow direction that user presses with the function all_go_up(down, left or right). And then add a new number with the add_new_number function.
Here are some piece of those code I mentioned above:
void up_merge()
{
for(int i = 1; i < 4; i++) {
for(int j = 0; j < 4; j++) {
if(grid[i][j] > 0 && grid[i - 1][j] == grid[i][j]) {
while(grid[i - 1][j] == grid[i][j]) {
grid[i - 1][j] *= 2;
grid[i][j] = 0;
}
}
else if(grid[i][j] > 0 && grid[i - 1][j] == 0 && grid[i - 2][j] == grid[i][j]) {
while(grid[i - 2][j] == grid[i][j]) {
grid[i - 2][j] *= 2;
grid[i][j] = 0;
}
}
else if(grid[i][j] > 0 && grid[i - 1][j] == 0 && grid[i - 2][j] == 0 && grid[i - 3][j] == grid[i][j]) {
while(grid[i - 3][j] == grid[i][j]) {
grid[i - 3][j] *= 2;
grid[i][j] = 0;
}
}
}
}
}
void all_go_up()
{
for(int i = 3; i > 0; i--) {
for(int j = 0; j < 4; j++) {
if(grid[i][j] > 0 && grid[i - 1][j] == 0) {
grid[i - 1][j] = grid[i][j];
grid[i][j] = 0;
}
for(int k = 3; k > 0; k--) {
if(grid[k][j] > 0 && grid[k - 1][j] == 0) {
grid[k - 1][j] = grid[k][j];
grid[k][j] = 0;
}
}
}
}
}
bool add_new_number(int num)
{
int n = rand() % 2 + 1;
int newnumber = 1 << n;
int r, c;
switch(num) {
case 1: //up
r = rand() % 2 + 2;
c = rand() % 4;
break;
case 2: //down
r = rand() % 2;
c = rand() % 4;
break;
case 3: //left
r = rand() % 4;
c = rand() % 2 + 2;
break;
case 4: //right
r = rand() % 4;
c = rand() % 2;
break;
}
do {
if(check_empty() == 1) {
if(grid[r][c] == 0) {
grid[r][c] = newnumber;
return false;
}
if(grid[r][c] != 0) {
switch(num) {
case 1: //up
r = rand() % 2 + 2;
c = rand() % 4;
break;
case 2: //down
r = rand() % 2;
c = rand() % 4;
break;
case 3: //left
r = rand() % 4;
c = rand() % 2 + 2;
break;
case 4: //right
r = rand() % 4;
c = rand() % 2;
break;
}
}
}
else {
return false;
}
} while(true);
}
I have some other functions to check whether the grid is full and so on. I also tried use some while() and for() to do this, too. But I do not know where I get wrong to code the function to test whether the game is over.
I hope I express my problem well. Hoping to get some suggestions to code the test_fail function without changing too much of my code. Thanks.
With all the respect, your code looks totally unreadable. Consider functional approach where you compose few smaller function to break down more complex problem. I am going to demonstrate this in Typescript but it would be very similar in C++. In this way the code is I believe self-explanatory.
type Board = number[][]
function isGameOver(board: Board) {
if (hasEmptySpace(board)) return false
return checkHorizontalGameOver(board) && checkVerticalGameOver(board)
}
function hasEmptySpace(board: Board) {
for (let r = 0; r < NUM_ROWS; r++) {
for (let c = 0; c < NUM_COLS; c++) {
if (board[r][c] === 0) return true
}
}
return false
}
function checkHorizontalGameOver(board: Board) {
for (let i = 0; i < NUM_ROWS; i++) {
for (let j = 0; j < NUM_COLS - 1; j++) {
if (board[i][j] === board[i][j + 1]) return false
}
}
return true
}
function checkVerticalGameOver(board: Board) {
for (let i = 0; i < NUM_ROWS - 1; i++) {
for (let j = 0; j < NUM_COLS; j++) {
if (board[i][j] === board[i + 1][j]) return false
}
}
return true
}
I understand it's 5 years ago as I am reading now and your skills in programming are far far better, but still - I will post it here for people who might come across this so it can possibly help them.
this code attempts to solve the 4 queens problem, placing 4 queens on a 4*4 chessboard without any of them being able to capture eachother
#include <iostream>
using namespace std;
int Place(int Chess[][4], int collumn, int i);
bool Check(int Chess[][4], int collumn, int i);
int findrow(int Chess[][4], int collumn);
const int size = 3;
int main()
{
int Chess[4][4];
int collumn;
int i = 0;
collumn = 0;
for(int s = 0; s < 4; s++)
{
for(int j = 0; j < 4; j ++)
{
Chess[s][j] = 0;
}
}
//Chess[0][0] = 1;
//Chess[3][3] = 1;
//if(Check(Chess, 3, 3) == false)
Place(Chess, collumn, i);
for(int z = 0; z < 4; z++)
{
for(int a = 0; a < 4; a++)
{
if(Chess[z][a] == 1)
cout<<"Row: "<<z<<"Collumn: "<<a<<"."<<endl;
}
cout<<endl;
}
system("pause");
return 0;
}
int Place(int Chess[][4], int collumn, int i)
{
if(collumn > size)
return 0;
while(i <= size)
{
if(Check(Chess, collumn, i) == true)
{
//cout<<"hi"<<endl;
Chess[collumn][i] = 1;
return(Place(Chess, (collumn + 1), i));
}
i ++;
}
if(i>= size)
{
//cout<<"hilo"<<endl;
return Place(Chess, collumn-1, findrow(Chess, collumn-1));
}
}
bool Check(int Chess[][4], int collumn, int i)//checks to see if it can be captured
{// very inneficitnt
int x = collumn;// this is so we can now work in terms of x and y
int y = i;
bool found = true;
// checks all the diagonal captures
if(Chess[x -1 ][y -1]== 1&& x>=1 && y >=1 )
found = false;
if(Chess[x -2 ][y - 2]== 1&& x>=2 && y>=2 )
found = false;
if(Chess[x - 3][y - 3]== 1 && x>=3 && y>=3 )
found = false;
if(Chess[x + 1][y - 1] == 1&& x<=2 && y>=1 )
found = false;
if(Chess[x + 2][y -2] == 1&& x<=1 && y>=2)
found = false;
if(Chess[x + 3][y - 3] == 1 && x<=0 && y>=3)
found = false;
if(Chess[x + 1][y + 1] == 1 && x<=2 && y<=2)
found = false;
if(Chess[x + 2][y + 2] == 1&& x<=1 && y<=1)
found = false;
if(Chess[x + 3][y + 3] == 1 && x<=0 && y<=0 )
found = false;
if(Chess[x -1 ][y + 1]== 1 && x>=1 && y<=2 )
found = false;
if(Chess[x - 2][y + 2] == 1&& x>=2 && y<=1 )
found = false;
if(Chess[x - 3][y + 3] == 1&& x>=3 && y<=0)
found = false;
//checks all the horizontal captures. We don't need to check for vertical captures
if(Chess[x + 1][y] == 1 && x<=2)
found = false;
if(Chess[x + 2][y] == 1&& x<=1 )
found = false;
if(Chess[x+3][y] == 1 && x<=0)
found = false;
if(Chess[x -1 ][y] == 1&& x>=1)
found = false;
if(Chess[x-2][y] == 1&& x>=2 )
found = false;
if(Chess[x-3][y] == 1 && x>=3)
found = false;
if(found == false)
return false;
if(found == true)
return true;
}
int findrow(int Chess[][4], int collumn)
{
for(int z = 0; z < 4; z++)
{
if(Chess[collumn][z] == 1)
{
Chess[collumn][z] = 0;
return z;
}
}
}
The first thing I see is a probable out-of-bounds access:
if(Chess[x -1 ][y -1]== 1&& x>=1 && y >=1 )
What if the value of x is 0? You are accessing Chess[-1][y], which is out of bounds. Your if statement does not stop this, even with the x>=1 condition.
The if will first test the Chess[x-1][y-1]==1 condition. If you want this to not happen, place the test for x>=1 before Chess[x-1][y-1]==1.
But even with this, that entire section of code looks suspicious. I wouldn't be surprised if there were more out-of-bounds accesses.
I'm trying to make it where the character is in a tile and when they move up or down it moves to the next tile but I'm not sure how to do that. Right now, I have it set up where the character moves by pixels but I want it to move by 1 square.
The code right now is this, and it works, but it's glitchy in pixel mode. I believe if it was by blocks it might work better but I might change it anyway.
float spritewidth = sprite->stretchX;
float spriteheight = sprite->stretchY;
float bushwidth = bush->stretchX;
float bushheight = bush->stretchY;
//Basic border collision
if (sprite->x <= 0)
sprite->x = 0;
if (sprite->y <= 0)
sprite->y = 0;
if (sprite->x >= 455)
sprite->x = 455;
if (sprite->y >= 237)
sprite->y = 237;
if ( (sprite->x + spritewidth > bush->x) && (sprite->x < bush->x + bushwidth) && (sprite->y + spriteheight > bush->y) && (sprite->y < bush->y + bushheight) )
{
bushcol = 1;
}
else
{
bushcol = 0;
}
if (osl_keys->held.down)
{
if (bushcol == 1)
{
sprite->y = bush->y - spriteheight - 3;
bushcol = 0;
}
else
{
bushcol = 0;
sprite->y += 3;
}
}
if (osl_keys->held.up)
{
if (bushcol == 1)
{
sprite->y = bush->y + bushheight + 3;
bushcol = 0;
}
else
{
bushcol = 0;
sprite->y -= 3;
}
}
if (osl_keys->held.right)
{
if (bushcol == 1)
{
sprite->x = bush->x - spritewidth - 3;
bushcol = 0;
}
else
{
bushcol = 0;
sprite->x += 3;}
}
if (osl_keys->held.left)
{
if (bushcol == 1)
{
sprite->x = bush->x + bushwidth + 3;
bushcol = 0;
}
else
{
bushcol = 0;
sprite->x -= 3;
}
}
If you want the character to move one tile/square/block at a time, just move the sprite the number of pixels the tile is wide (or tall).
const int tile_width = 32; // or something
// and then
sprite->x += tile_width;