I'm making a simple maze program that generates a maze. Currently I was working on making one and only solution to a maze, when I stumbled onto something weird. When I debug this code I see that VS is just skipping my if statements here:
for (i = 0; i <= (col * row) / 200; i++)
{
solution[se[0]][se[1]] = 1;
if (lab[se[0] + 1][se[1]]) se[0] + 1;
else if (lab[se[0]][se[1] + 1]) se[1] + 1;
else if (lab[se[0] - 1][se[1]]) se[0] - 1;
else if (lab[se[0]][se[1] - 1]) se[1] - 1;
solution[se[2]][se[3]] = 1;
if (lab[se[2] - 1][se[3]]) se[2] - 1;
else if (lab[se[2]][se[3] - 1]) se[3] - 1;
else if (lab[se[2] + 1][se[3]]) se[2] + 1;
else if (lab[se[2]][se[3] + 1]) se[3] + 1;
}
I hope it's not a duplicate, but I have no slightest idea what's the problem here, so it could be one.
Here's the full code if someone wants to replicate the problem:
#include <stdio.h>
#include <iostream>
#include <Windows.h>
#include <string>
CONSOLE_SCREEN_BUFFER_INFO csbi;
int **lab, **solution;
int col, row, i, j;
int main() {
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
col = csbi.srWindow.Right - csbi.srWindow.Left; row = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; i = 0; j = 0;
lab = new int* [row];
for (i = 0; i < row; ++i)
lab[i] = new int[col];
solution = new int* [row];
for (i = 0; i < row; ++i)
solution[i] = new int[col];
for (i = 0; i < row; i++) { // Build basic maze
for (j = 0; j < col; j++) {
if (i == 0) lab[i][j] = 0;
else if (i == j == 1) lab[i][j] = 1;
else if (i == 1 && j == col - 1) lab[i][j] = 1;
else if (i == row - 1) lab[i][j] = 0;
else if (j == 0) lab[i][j] = 0;
else if (j == col - 1) lab[i][j] = 0;
else {
if (lab[i - 1][j] == 0) lab[i][j] = rand() % 2;
else {
if (lab[i - 1][j - 1] + lab[i - 1][j + 1] + lab[i - 2][j] <= 1) lab[i][j] = 1;
else {
lab[i][j] = rand() % 2;
}
}
}
}
}
int se[4] = { 1,1,1,col - 1 };
for (i = 0; i <= (col * row) / 200; i++) // Generate a solution
{
solution[se[0]][se[1]] = 1;
if (lab[se[0] + 1][se[1]]) se[0] + 1;
else if (lab[se[0]][se[1] + 1]) se[1] + 1;
else if (lab[se[0] - 1][se[1]]) se[0] - 1;
else if (lab[se[0]][se[1] - 1]) se[1] - 1;
solution[se[2]][se[3]] = 1;
if (lab[se[2] - 1][se[3]]) se[2] - 1;
else if (lab[se[2]][se[3] - 1]) se[3] - 1;
else if (lab[se[2] + 1][se[3]]) se[2] + 1;
else if (lab[se[2]][se[3] + 1]) se[3] + 1;
}
while (se[0] != se[2] || se[1] != se[3])
{
if (se[0] < se[2])
{
if (lab[se[2] - 1][se[3]]) se[2] - 1;
if (lab[se[0] + 1][se[1]]) se[0] + 1;
}
if (se[1] < se[3])
{
if (lab[se[2]][se[3] - 1]) se[3] + 1;
if (lab[se[0]][se[1] + 1]) se[1] + 1;
}
solution[se[0]][se[1]] = 1;
solution[se[2]][se[3]] = 1;
}
std::string out;
for (i = 0; i < row; i++) { // Print maze
for (j = 0; j < col; j++) {
if (solution[i][j]==1) out.append("#");
else if (!lab[i][j]) out.append("#");
else out.append(" ");;
}
std::cout << out << '\n';
out="";
}
system("pause");
for (i = 0; i < row; ++i) delete[] lab[i];
delete[] lab;
}
I'm sorry, this code is a mess, because it's still work in progress.
BTW I'm using VS 2019, didn't try it in another compiler yet. Is it really a compiler's fault?
The reason why the compiler sees fit to 'skip' the if blocks is because there is no code in them that has any effect!
For example, in the statement:
if (lab[se[0] + 1][se[1]]) se[0] + 1;
when the condition in the test is "true" what happens? The statement se[0] + 1 doesn't actually modify anything - it is simply an expression that has the given value.
What you probably want is to add 1 to se[0], so you need this:
if (lab[se[0] + 1][se[1]]) se[0] += 1;
and similarly for the other if and else if lines. (Note the added = character!)
Related
I have just successfully linked the SFML library to my Visual Studio 2019. I am trying to run a simple C++ game Minesweeper. It compiles, gives no error message, but gives weird unexpected results in the runtime window. It says failed to load images. Please help. This is a pic of the error message, and see code for game below.
Failed to load images pic
#include <SFML/Graphics.hpp>
#include <time.h>
using namespace sf;
int main()
{
srand(time(0));
RenderWindow app(VideoMode(400, 400), "Minesweeper!");
int w = 32;
int grid[12][12];
int sgrid[12][12]; //for showing
Texture t;
t.loadFromFile("images/tiles.jpg");
Sprite s(t);
for (int i = 1; i <= 10; i++)
for (int j = 1; j <= 10; j++)
{
sgrid[i][j] = 10;
if (rand() % 5 == 0) grid[i][j] = 9;
else grid[i][j] = 0;
}
for (int i = 1; i <= 10; i++)
for (int j = 1; j <= 10; j++)
{
int n = 0;
if (grid[i][j] == 9) continue;
if (grid[i + 1][j] == 9) n++;
if (grid[i][j + 1] == 9) n++;
if (grid[i - 1][j] == 9) n++;
if (grid[i][j - 1] == 9) n++;
if (grid[i + 1][j + 1] == 9) n++;
if (grid[i - 1][j - 1] == 9) n++;
if (grid[i - 1][j + 1] == 9) n++;
if (grid[i + 1][j - 1] == 9) n++;
grid[i][j] = n;
}
while (app.isOpen())
{
Vector2i pos = Mouse::getPosition(app);
int x = pos.x / w;
int y = pos.y / w;
Event e;
while (app.pollEvent(e))
{
if (e.type == Event::Closed)
app.close();
if (e.type == Event::MouseButtonPressed)
if (e.key.code == Mouse::Left) sgrid[x][y] = grid[x][y];
else if (e.key.code == Mouse::Right) sgrid[x][y] = 11;
}
app.clear(Color::White);
for (int i = 1; i <= 10; i++)
for (int j = 1; j <= 10; j++)
{
if (sgrid[x][y] == 9) sgrid[i][j] = grid[i][j];
s.setTextureRect(IntRect(sgrid[i][j] * w, 0, w, w));
s.setPosition(i * w, j * w);
app.draw(s);
}
app.display();
}
return 0;
}
I would like to use this "Levenshtein" function to assess similarities between two strings (to check if user has committed a spelling mistake).
Since I work on null safe mode, it points out an error with the LIST constructor :
List<List<int>> d = List.generate(sa + 1, (int i) => List(sb + 1));
What can I write to replace List(sb+1)); ?
int levenshtein(String a, String b) {
a = a.toUpperCase();
b = b.toUpperCase();
int sa = a.length;
int sb = b.length;
int i, j, cost, min1, min2, min3;
int levenshtein;
// ignore: deprecated_member_use
List<List<int>> d = List.generate(sa + 1, (int i) => List(sb + 1));
if (a.length == 0) {
levenshtein = b.length;
return (levenshtein);
}
if (b.length == 0) {
levenshtein = a.length;
return (levenshtein);
}
for (i = 0; i <= sa; i++) d[i][0] = i;
for (j = 0; j <= sb; j++) d[0][j] = j;
for (i = 1; i <= a.length; i++)
for (j = 1; j <= b.length; j++) {
if (a[i - 1] == b[j - 1])
cost = 0;
else
cost = 1;
min1 = (d[i - 1][j] + 1);
min2 = (d[i][j - 1] + 1);
min3 = (d[i - 1][j - 1] + cost);
d[i][j] = min(min1, min(min2, min3));
}
levenshtein = d[a.length][b.length];
return (levenshtein);
}
You can use List.generate for the inner list as well.
List<List<int>> d = List.generate(sa + 1, (int i) => List.generate(sb + 1, (int j) => 0));
Also, if they're all going to be initialized to 0 you can just do this too:
List<List<int>> d = List.filled(sa + 1, List.filled(sb + 1, 0));
#include <vector>
using namespace std;
int solution(int m, int n, vector<vector<int>> puddles) {
const int MAXIMUM = 100;
int paddlePosition = -1;
int pos[MAXIMUM][MAXIMUM] {0}; //type 1
//int pos[MAXIMUM][MAXIMUM]; //type 2
for(auto puddle = puddles.begin(); puddle != puddles.end(); puddle++)
pos[(*puddle)[1] - 1][(*puddle)[0] - 1] = paddlePosition;
pos[0][0] = 1;
for(int i = 1; i < m; i++)
if(pos[0][i] != paddlePosition)
pos[0][i] = pos[0][i - 1];
for(int i = 1; i < n; i++)
if(pos[i][0] != paddlePosition)
pos[i][0] = pos[i - 1][0];
for(int i = 1; i < n; i++)
{
for(int j = 1; j < m; j++)
{
if(pos[i][j] == paddlePosition);
else if(pos[i - 1][j] == paddlePosition && pos[i][j - 1] == paddlePosition)
pos[i][j] = paddlePosition;
else if(pos[i - 1][j] == paddlePosition)
pos[i][j] = pos[i][j - 1];
else if(pos[i][j - 1] == paddlePosition)
pos[i][j] = pos[i - 1][j];
else
pos[i][j] = (pos[i - 1][j] + pos[i][j - 1]) % 1000000007;
}
}
int answer = pos[n - 1][m - 1];
if(answer == paddlePosition)
answer = 0;
return answer;
}
this code has only one difference. pos array have initialization or not.
when i give parameter m = 100, n = 100, puddles = [[1, 1]] and access to pos[99][99], the value doesn't fixed without initialization.
i thought that double for phrase access data continously and boundary of array was initialized already so data will doesn't mattered without initialization(working like lazy initialization). but it was wrong.
why result is difference?
Hello I have been attempting to add a scoring scheme which is 11 for internal gaps, 8 for terminal gaps on the 5 prime end, 7 for gaps on the 3' end, 4 for mismatches, 0 for matches. Currently the code only accounts for internal gap (= 11), mismatches(= 4) and matches (=0) but not for terminal gaps. Im fairly new to coding so I apologise in advance if my code is messy, any guidance is appreciated. I should be getting a score of 275.
The two sequences I used are included in the code.
#include <iostream>
#include <fstream>
#include <bits/stdc++.h>
using namespace std;
void getscore(string x, string y, int pxy, int pgap)
{
int i, j;
int m = x.length();
int n = y.length();
int dp[n+m+1][n+m+1] = {0};
for (i = 0; i <= (n+m); i++)
{
dp[i][0] = i * pgap;
dp[0][i] = i * pgap;
}
for (i = 1; i <= m; i++)
{
for (j = 1; j <= n; j++)
{
if (x[i - 1] == y[j - 1])
{
dp[i][j] = dp[i - 1][j - 1];
}
else
{
dp[i][j] = min({dp[i - 1][j - 1] + pxy ,
dp[i - 1][j] + pgap ,
dp[i][j - 1] + pgap });
}
}
}
int l = n + m;
i = m; j = n;
int xpos = l;
int ypos = l;
int xans[l+1], yans[l+1];
while ( !(i == 0 || j == 0))
{
if (x[i - 1] == y[j - 1])
{
xans[xpos--] = (int)x[i - 1];
yans[ypos--] = (int)y[j - 1];
i--; j--;
}
else if (dp[i - 1][j - 1] + pxy == dp[i][j])
{
xans[xpos--] = (int)x[i - 1];
yans[ypos--] = (int)y[j - 1];
i--; j--;
}
else if (dp[i - 1][j] + pgap == dp[i][j])
{
xans[xpos--] = (int)x[i - 1];
yans[ypos--] = (int)'_';
i--;
}
else if (dp[i][j - 1] + pgap == dp[i][j])
{
xans[xpos--] = (int)'_';
yans[ypos--] = (int)y[j - 1];
j--;
}
}
while (xpos > 0)
{
if (i > 0) xans[xpos--] = (int)x[--i];
else xans[xpos--] = (int)'_';
}
while (ypos > 0)
{
if (j > 0) yans[ypos--] = (int)y[--j];
else yans[ypos--] = (int)'_';
}
int id = 1;
for (i = l; i >= 1; i--)
{
if ((char)yans[i] == '_' && (char)xans[i] == '_')
{
id = i + 1;
break;
}
}
// Printing the final answer
cout << "Optimal score = ";
cout << dp[m][n] << "\n";
cout << "Optimal alignment :\n";
for (i = id; i <= l; i++)
{
cout<<(char)xans[i];
}
cout << "\n";
for (i = id; i <= l; i++)
{
cout << (char)yans[i];
}
return;
}
int main(){
string geneA = "TCTGGTGTCCTAGGCGTAGAGGAACCACACCAATCCATCCCGAACTCTGGTGGTTAAACTCTACTGCGGTGACGATACT ";
string geneB = "TGGTGCGGTCATACCAGCGCTAATGCACCGGATCCCATCAGAACTCCGCAGTTAAGCGCGCTTGGGCCAGAACAGTACTGGGATGGGTGTCC ";
int misMatchPenalty = 4;
int gapPenalty = 11;
int tPenalty=7;
int fPenalty=8;
getscore(geneA, geneB,
misMatchPenalty, gapPenalty);
return 0;
}
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.