I couldn't solve the problem myself, even reading answers to related questions (I already searched in stackoverflow, but I couldn't understand the proposed solutions or adapt them to my case).
This is the code the draws the grid:
// global variables
int cameraOffsetX = SCREEN_WIDTH / 2; //x coordinate of the "origin"
int cameraOffsetY = SCREEN_HEIGHT / 2;
int cameraZoomSpriteSize = 32; //size of a square in the current zoom
float zoomFactor = 1;
--------------------
//grid
SDL_SetRenderDrawColor(renderer, 0xe6, 0xe6, 0xe6, SDL_ALPHA_OPAQUE);
for (int i = cameraOffsetX - cameraOffsetX / cameraZoomSpriteSize * cameraZoomSpriteSize;
i < window_width; i += cameraZoomSpriteSize)
SDL_RenderDrawLine(renderer, i, 0, i, window_height);
for (int i = cameraOffsetY - cameraOffsetY / cameraZoomSpriteSize * cameraZoomSpriteSize;
i < window_height; i += cameraZoomSpriteSize)
SDL_RenderDrawLine(renderer, 0, i, window_width, i);
//origin
SDL_SetRenderDrawColor(renderer, 0xff, 0, 0, SDL_ALPHA_OPAQUE);
SDL_RenderDrawLine(renderer, cameraOffsetX, cameraOffsetY - cameraZoomSpriteSize, cameraOffsetX,
cameraOffsetY + cameraZoomSpriteSize);
SDL_RenderDrawLine(renderer, cameraOffsetX - cameraZoomSpriteSize, cameraOffsetY,
cameraOffsetX + cameraZoomSpriteSize, cameraOffsetY);
and this is the code that attempts to obtain the wanted behaviour which isn't quite right yet:
case SDL_MOUSEWHEEL:
int mx, my;
SDL_GetMouseState(&mx, &my);
if (event.wheel.y > 0) // scroll up
{
if (cameraZoomSpriteSize < 64) {
cameraOffsetX-=(mx-cameraOffsetX)*4/cameraZoomSpriteSize+(mx-cameraOffsetX)%cameraZoomSpriteSize*4/cameraZoomSpriteSize;
cameraOffsetY-=(my-cameraOffsetY)*4/cameraZoomSpriteSize+(my-cameraOffsetY)%cameraZoomSpriteSize*4/cameraZoomSpriteSize;
cameraZoomSpriteSize += 4;
zoomFactor += 0.125;
}
} else if (event.wheel.y < 0) // scroll down
{
if (cameraZoomSpriteSize > 4) {
cameraOffsetX+=(mx-cameraOffsetX)*4/cameraZoomSpriteSize+(mx-cameraOffsetX)%cameraZoomSpriteSize*4/cameraZoomSpriteSize;
cameraOffsetY+=(my-cameraOffsetY)*4/cameraZoomSpriteSize+(my-cameraOffsetY)%cameraZoomSpriteSize*4/cameraZoomSpriteSize;
cameraZoomSpriteSize -= 4;
zoomFactor -= 0.125;
}
}
break;
What are the correct formula for cameraOffsetX and cameraOffsetY. Unfortunately I couldn't visualize the math.
General principle:
cameraOffsetX = mx + (cameraOffsetX - mx) * newZoomCoefficient / oldZoomCoefficient
The solution I read here was right; only I couldn't translate right away zoompointX and scalechange.
I drew segments on a piece of paper and tried to scale them to figure out the same exact formula of that post.
case SDL_MOUSEWHEEL:
int mx, my;
SDL_GetMouseState(&mx, &my);
if (event.wheel.y > 0) // scroll up
{
if (cameraZoomSpriteSize < 64) {
cameraOffsetX-=(mx-cameraOffsetX)*4/cameraZoomSpriteSize;
cameraOffsetY-=(my-cameraOffsetY)*4/cameraZoomSpriteSize;
cameraZoomSpriteSize += 4;
zoomFactor += 0.125;
}
} else if (event.wheel.y < 0) // scroll down
{
if (cameraZoomSpriteSize > 4) {
cameraOffsetX+=(mx-cameraOffsetX)*4/cameraZoomSpriteSize;
cameraOffsetY+=(my-cameraOffsetY)*4/cameraZoomSpriteSize;
cameraZoomSpriteSize -= 4;
zoomFactor -= 0.125;
}
}
break;
This problem took me half of yesterday and this morning to solve :(
To begin with I am using the Chili Framework for lessons 1-15 as downloadable here:
http://www.planetchili.net/
I am using DirectX 9 on an old laptop running Windows XP SP3. I have set the Direct3D rendering to software in order to run the framework. I am using Visual Studio Express C++ 2010 with the first service pack installed.
This is the code I am having trouble with:
// Start moving reticle code
DrawReticle(itemLocX, itemLocY, 255, 255, 255);
if(itemLocX == pointA && itemLocX != pointAb)
{
itemLocX += 2;
}
else if(itemLocX == pointBc && itemLocX != pointDa)
{
itemLocX -= 2;
}
if(itemLocY == pointAb && itemLocY != pointBc)
{
itemLocY += 2;
}
else if(itemLocY == pointDa && itemLocX != pointA)
{
itemLocY -= 2;
}
// End moving reticle code
Now Chili's solution is to move along the y axis while checking for x, and x while checking for y. I may post that later, don't have it readily available. You can see it at the beginning of this video:
http://youtu.be/JEmwkQsi8l0
However I wanted to do this logically, as if I was walking the border along an invisible wall inside a box. I wanted it to make sense what was going on. But the cursor won't move, and I see no reason why it doesn't. Here is my game.h:
#pragma once
#include "D3DGraphics.h"
#include "Keyboard.h"
class Game
{
public:
Game( HWND hWnd,const KeyboardServer& kServer );
void Go();
private:
void ComposeFrame();
/********************************/
/* User Functions */
void DrawReticle(int xP, int yP, int cR, int cG, int cB);
/*
xP = x position,
yP = y position,
cR = color red,
cG = color green,
cB = color blue
*/
// TODO: User functions go here
/********************************/
private:
D3DGraphics gfx;
KeyboardClient kbd;
/********************************/
/* User Variables */
int pointA; // Starting at pointA (100, 100) - the top left
int pointAb; // Move from pointA to pointAb (700, 100) - the top right
int pointBc; // Move from pointAb to pointBc (700, 500) - the bottom right
int pointCd; // Move from pointBc to pointCd (100,500) - the bottom left
int pointDa; // Move from pointCd to pointDa (100,100) - the top left
/*
These points describe the process of starting, then four movements. The four points are A, B, C, D. We start at A, then go to B (pointAb, read as A to b), then go to C (pointBc, read as B to c), then go to D (pointCd, read as C to d) then go to A (pointDa, read as D to a).
This can be very confusing, because there are five varibles used. But if we drew it out there would only four points, as well as only four movements. The best way to think of it is that starting is itself a movement, and as you need a place to start from, it itself must have a point. Since you start at A, but haven't yet gone anywhere, pointA is our starting point. Once you start moving, you go from pointA to pointB. Now if we used pointB as our variable it would be confusing,because we would have to move from pointA to pointB to pointC to pointD and then back to pointA. Still five variables, one is repeating, but the first pointA describes where you start, and the last where you end. Since these are two different actions on the same point, I have elected to use two letter names for each of the points you move to, while the point you start at has a single letter name. It was the best way I could clearly think about this process.
*/
int itemLocX; // Initial position of item on the x axis
int itemLocY; // Initial position of item on the y axis
int reticleX; // Initial position of reticle on the x axis
int reticleY; // Initial position of reticle on the y axis
// TODO: User variables go here
/********************************/
};
Here is my game.cpp:
#include "Game.h"
Game::Game( HWND hWnd,const KeyboardServer& kServer )
: gfx(hWnd),
kbd(kServer),
itemLocX(100), // Initial position of item on the x axis
itemLocY(100), // Initial position of item on the y axis
reticleX(400), // Initial position of reticle on the x axis
reticleY(300), // Initial position of reticle on the y axis
pointA(100), // Movement from 0 to A, stopping at A
pointAb(700), // Movement from A to b, stopping at B
pointBc(500), // Movement from B to c, stopping at C
pointCd(700), // Movement from C to d, stopping at D
pointDa(500) // Movement from D to a, stopping at A
{}
void Game::Go()
{
gfx.BeginFrame();
ComposeFrame();
gfx.EndFrame();
}
void Game::DrawReticle(int xP, int yP, int cR, int cG, int cB)
/*
xP = x position,
yP = y position,
cR = color red,
cG = color green,
cB = color blue
*/
{
gfx.PutPixel(xP-5,yP,cR,cG,cB);
gfx.PutPixel(xP-4,yP,cR,cG,cB);
gfx.PutPixel(xP-3,yP,cR,cG,cB);
gfx.PutPixel(xP+3,yP,cR,cG,cB);
gfx.PutPixel(xP+4,yP,cR,cG,cB);
gfx.PutPixel(xP+5,yP,cR,cG,cB);
gfx.PutPixel(xP,yP,cR,cG,cB);
gfx.PutPixel(xP,yP-5,cR,cG,cB);
gfx.PutPixel(xP,yP-4,cR,cG,cB);
gfx.PutPixel(xP,yP-3,cR,cG,cB);
gfx.PutPixel(xP,yP+3,cR,cG,cB);
gfx.PutPixel(xP,yP+4,cR,cG,cB);
gfx.PutPixel(xP,yP+5,cR,cG,cB);
}
void Game::ComposeFrame()
{
// Start draw reticle code
DrawReticle(reticleX, reticleY, 100, 155, 255);
// End draw reticle code
// Start color change code
int yT = 200; // Border 200 pixels from top
int yB = 400; // Border 200 pixels from bottom
int xL = 300; // Border 200 pixels from left
int xR = 500; // Border 200 pixels from right
if(reticleX < xL || reticleX > xR) // Defining color change area for X
{
DrawReticle(reticleX, reticleY, 255, 255, 255);
}
if(reticleY < yT || reticleY > yB) // Defining color change area for Y
{
DrawReticle(reticleX, reticleY, 255, 255, 255);
}
// End color change code
// Start moving reticle code
DrawReticle(itemLocX, itemLocY, 255, 255, 255);
if(itemLocX == pointA && itemLocX != pointAb)
{
itemLocX += 2;
}
else if(itemLocX == pointBc && itemLocX != pointDa)
{
itemLocX -= 2;
}
if(itemLocY == pointAb && itemLocY != pointBc)
{
itemLocY += 2;
}
else if(itemLocY == pointDa && itemLocX != pointA)
{
itemLocY -= 2;
}
// End moving reticle code
// Start border code
if(reticleX < 6)
{
reticleX = 6;
}
else if(reticleX > 794)
{
reticleX = 794;
}
if(reticleY < 6)
{
reticleY = 6;
}
else if(reticleY > 594)
{
reticleY = 594;
}
// End border code
// Start speed change code
int cSpeed = 4; // Default cursor speed
if(kbd.EnterIsPressed()) // Change to high speed
{
cSpeed = 8;
}
if(kbd.SpaceIsPressed()) // Change to low speed
{
cSpeed = 1;
}
if(kbd.RightIsPressed())
{
reticleX += cSpeed;
}
if(kbd.LeftIsPressed())
{
reticleX -= cSpeed;
}
if(kbd.UpIsPressed())
{
reticleY -= cSpeed;
}
if(kbd.DownIsPressed())
{
reticleY += cSpeed;
}
// End speed change code
}
Now I should note here that this should be done without functions and only the basic C++ operators. That's as far as Chili has taught to this point. This is my second attempt to solve this myself, after hours thinking about it and working on it on paper. I'm stuck. Just not seeing it. I think there is a logic error here on my part. I want to understand where my thinking may be mistaken, but more than that, how to think correctly, like the computer, about this.
I am also open to advice regarding my coding style. If I am not being clear enough, or am doing something that should not become a bad habit - basically if there is something I should be doing differently in writing my code I would like to know about it.
Thank you for your help - it is very much appreciated!
I see how you have tried to do this. Personally you have over complexed it.
1: you don't need the != operator in your if statements.
2: try this:
if(itemLocX < 700)
{
itemLocX += 2;
}
3: This worked fine during testing. Another point is that the if statements could be in the wrong order. I changed it to the order in which it moved across the screen in. I have X Y X Y and you have X X Y Y. (unconfirmed) It executes the if statements in order. I have hard coded the answer. set them to variables if you really want to. Hope this helped!
I'm writing a Nine Men's Morris game and so far I have a Negascout search that works just fine. However, I would like to added iterative deepening, so I came up with this code:
public Move GetBestMove(IBoard board, int depth)
{
//Search limits (ms
this.maxTime = 9000;
//Set initial window
int alpha = -INFINITY, beta = INFINITY;
int val = 0;
//The move that will be returned
Move bestMove = null;
//Get list of moves for the current board
List<Move> moves = board.getMoves();
//Get the time search has started
long startTime = System.nanoTime();
//Iterate through the depths
for (curDepth = 1; ; )
{
maxDepth = curDepth;
//Reset alpha
alpha = -INFINITY;
//Reset the best score position
int bestPos = -1;
//Loop through all the moves
for (int i = 0, n = moves.size(); i < n; i++)
{
//Make the move
board.make(moves.get(i), true);
//Search deeper
val = negascout(board, curDepth, alpha, beta, startTime);
//Undo the move
board.undo(moves.get(i));
//Keep best move
if (val > alpha)
{
bestMove = moves.get(i);
bestPos = i;
}
//Score missed aspiration window
if (val <= alpha || val >= beta)
{
alpha = -INFINITY;
beta = INFINITY;
//Go to next iteration
continue;
}
//Set new aspiration window
alpha = val - ASPIRATION_SIZE;
if (alpha < -INFINITY)
alpha = -INFINITY;
beta = val + ASPIRATION_SIZE;
if (beta > INFINITY)
beta = INFINITY;
}
//Move the best move to the top of the list
if (bestPos != -1)
{
moves.remove(bestPos);
moves.add(0, bestMove);
}
//Time check
double curTime = (System.nanoTime() - startTime) / 1e6;
if (curTime >= maxTime ||
val == board.getMaxScoreValue() ||
val == -board.getMaxScoreValue())
break;
//Increment current depth
curDepth++;
}
//Return the move
return bestMove;
}
I also use an aspiration window. However, the search returns the worst possible move!! I think that the problem is with re-/setting the search window. Should the search window be moved to the outer loop?
Since you're using negascout, your initial call should look like
val = -negascout(board, curDepth - 1, -beta, -alpha, startTime);
Your root call is the exact opposite compared to internal nodes, so that explains why it's returning the worst possible move.
The iterative deepening strategy:
for (depth = 1;; depth++) {
val = AlphaBeta(depth, -INFINITY, INFINITY); // or negascout
if (TimedOut())
break;
}
looks different to the one you implemented with GetBestMove. The inner loop (iterating through the possible moves) should be part of negascout. Further it seems, that you only store the move ordering at first depth level (1-ply), but to make the iterative deepening search really fast, it needs a move ordering at every depth searched so far. Iterative deepening not only has the advantage to take time into account (finish after x seconds), but also has the advantage of generating a good move ordering. And the alphabeta or negascout algorithm benefits from a good move ordering (try this move first because in a previous search it was the best). A common way to get a move ordering implemented is the transposition table.
The documents The Main Transposition Table and Iterative Deepening from Bruce Moreland where very helpful to me and I hope that the links can help you too!
Ok, so I have a histogram (represented by an array of ints), and I'm looking for the best way to find local maxima and minima. Each histogram should have 3 peaks, one of them (the first one) probably much higher than the others.
I want to do several things:
Find the first "valley" following the first peak (in order to get rid of the first peak altogether in the picture)
Find the optimum "valley" value in between the remaining two peaks to separate the picture
I already know how to do step 2 by implementing a variant of Otsu.
But I'm struggling with step 1
In case the valley in between the two remaining peaks is not low enough, I'd like to give a warning.
Also, the image is quite clean with little noise to account for
What would be the brute-force algorithms to do steps 1 and 3? I could find a way to implement Otsu, but the brute-force is escaping me, math-wise. As it turns out, there is more documentation on doing methods like otsu, and less on simply finding peaks and valleys. I am not looking for anything more than whatever gets the job done (i.e. it's a temporary solution, just has to be implementable in a reasonable timeframe, until I can spend more time on it)
I am doing all this in c#
Any help on which steps to take would be appreciated!
Thank you so much!
EDIT: some more data:
most histogram are likely to be like the first one, with the first peak representing background.
Use peakiness-test. It's a method to find all the possible peak between two local minima, and measure the peakiness based on a formula. If the peakiness higher than a threshold, the peak is accepted.
Source: UCF CV CAP5415 lecture 9 slides
Below is my code:
public static List<int> PeakinessTest(int[] histogram, double peakinessThres)
{
int j=0;
List<int> valleys = new List<int> ();
//The start of the valley
int vA = histogram[j];
int P = vA;
//The end of the valley
int vB = 0;
//The width of the valley, default width is 1
int W = 1;
//The sum of the pixels between vA and vB
int N = 0;
//The measure of the peaks peakiness
double peakiness=0.0;
int peak=0;
bool l = false;
try
{
while (j < 254)
{
l = false;
vA = histogram[j];
P = vA;
W = 1;
N = vA;
int i = j + 1;
//To find the peak
while (P < histogram[i])
{
P = histogram[i];
W++;
N += histogram[i];
i++;
}
//To find the border of the valley other side
peak = i - 1;
vB = histogram[i];
N += histogram[i];
i++;
W++;
l = true;
while (vB >= histogram[i])
{
vB = histogram[i];
W++;
N += histogram[i];
i++;
}
//Calculate peakiness
peakiness = (1 - (double)((vA + vB) / (2.0 * P))) * (1 - ((double)N / (double)(W * P)));
if (peakiness > peakinessThres & !valleys.Contains(j))
{
//peaks.Add(peak);
valleys.Add(j);
valleys.Add(i - 1);
}
j = i - 1;
}
}
catch (Exception)
{
if (l)
{
vB = histogram[255];
peakiness = (1 - (double)((vA + vB) / (2.0 * P))) * (1 - ((double)N / (double)(W * P)));
if (peakiness > peakinessThres)
valleys.Add(255);
//peaks.Add(255);
return valleys;
}
}
//if(!valleys.Contains(255))
// valleys.Add(255);
return valleys;
}
I'm writing a Conway's life game for school. In the program I am having trouble with the arrays taking the values I am assigning them. At one point in the program they print out the value assigned to them (1) yet at the end of the program when I need to print the array to show the iterations of the game it shows an incredibly low number. The other trouble was I was encountering difficulties when putting in a loop that would ask if it wants you to run another iteration. So I removed it until the previous errors were fixed.
Im writing this with C++
#include <stdio.h>
int main (void)
{
int currentarray [12][12];
int futurearray [12][12];
char c;
char check = 'y';
int neighbors = 0;
int x = 0; // row
int y = 0; //column
printf("Birth an organism will be born in each empty location that has exactly three neighbors.\n");
printf("Death an organism with four or more organisms as neighbors will die from overcrowding.\n");
printf("An organism with fewer than two neighbors will die from loneliness.\n");
printf("Survival an organism with two or three neighbors will survive to the next generation.\n");
printf( "To create life input x, y coordinates.\n");
while ( check == 'y' )
{
printf("Enter x coordinate.\n");
scanf("%d", &x ); while((c = getchar()) != '\n' && c != EOF);
printf("Enter y coordinate.\n");
scanf("%d", &y ); while((c = getchar()) != '\n' && c != EOF);
currentarray [x][y] = 1;
printf ("%d\n", currentarray[x][y]);
printf( "Do you wish to enter more input? y/n.\n");
scanf("%c", &check); while((c = getchar()) != '\n' && c != EOF);
}
// Note - Need to add a printf statement showing the array before changes are made after input added.
// check for neighbors
while(check == 'y')
{
for(y = 0; y <= 12; y++)
{
for(x = 0; x <= 12; x++)
{
//Begin counting number of neighbors:
if(currentarray[x-1][y-1] == 1) neighbors += 1;
if(currentarray[x-1][y] == 1) neighbors += 1;
if(currentarray[x-1][y+1] == 1) neighbors += 1;
if(currentarray[x][y-1] == 1) neighbors += 1;
if(currentarray[x][y+1] == 1) neighbors += 1;
if(currentarray[x+1][y-1] == 1) neighbors += 1;
if(currentarray[x+1][y] == 1) neighbors += 1;
if(currentarray[x+1][y+1] == 1) neighbors += 1;
//Apply rules to the cell:
if(currentarray[x][y] == 1 && neighbors < 2)
futurearray[x][y] = 0;
else if(currentarray[x][y] == 1 && neighbors > 3)
futurearray[x][y] = 0;
else if(currentarray[x][y] == 1 && (neighbors == 2 || neighbors == 3))
futurearray[x][y] = 1;
else if(currentarray[x][y] == 0 && neighbors == 3)
futurearray[x][y] = 1;
}
}
}
// Set the current array to the future and change the future to 0
{
for(y = 0; y < 12; y++)
{
for(x = 0; x < 12; x++)
{
//Begin the process
currentarray [x][y] = futurearray [x][y];
futurearray [x][y] = 0;
}
}
}
{
for(y = 0; y < 12; y++)
{
for(x = 0; x < 12; x++)
{
//print the current life board
printf("%d ", currentarray[x][y]);
}
}
}
// Have gone through one iteration of Life
//Ask to do another iteration
printf("Do you wish to continue y/n?\n");
scanf("%c", &check); while((c = getchar()) != '\n' && c != EOF);
return 0;
}
You are defining your arrays as [12][12].
In your generation loop you walk from i = 0 to i <= 12, which is 13 steps instead of the 12 of the array. Additionally you are trying to access x-1 and y-1, which can be as low as -1. Again not inside your array.
Sometimes you get semi-useful values from within your array, but on some borders you are just accessing random data.
Try to correct your border.
You forgot to set neighbors to 0 before counting them.
Since this is C++ (not C), you might as well declare neighbors inside the loop body. Makes these kinds of issues easier to spot, too.
Also, is it me, or is that while loop never going to finish? Your braces are a mess, in general, as is your indentation. You could do yourself and us a favour by cleaning those up.
Obviously agree with all the above suggestions. One nice trick you might want to implement with Life is to create an extra border around your area. So if the user wants a 12x12 grid (and you should allow width/height to be specified and allocate memory dynamically) internally you hold a 14x14 grid corresponding to a border around the actual grid. Before running the calculation copy the top row to the bottom border, bottom row to the top border etc. Now you can run the main algorithm on the inner 12x12 grid without worrying about edge cases. This will enable your patterns to re-appear on the other side if they fall off the edge.
You're also forgetting to set the values of both arrays to zero. This will take care of the ridiculous number issue you're having. you can do that by copying this for loop:
for(y = 0; y < 12; y++)
{
for(x = 0; x < 12; x++)
{
//Begin the process
currentarray [x][y] = futurearray [x][y];
futurearray [x][y] = 0;
}
}
and pasting it before the while loop but instead of setting currentarray[x][y] = futurearray[x][y], set it to 0. Also, if the coordinates are viewable locations instead of array co-ordinates, you'll want to change this:
printf ("%d\n", currentarray[x][y]);
to this:
printf ("%d\n", currentarray[x-1][y-1]);
I would also recommend putting a printf with a newline (\n) after each row has been printed and a tab (\t) after each item so that the formatting looks cleaner.