I'm trying to build a rubik's cube solver in C using the Thistlethwaite algorithm.
I'm storing a cube as an array of 6 uint64_t integers (Faces).
Each of this faces stores 8 colors as one byte.
This structure let's me easily rotate faces using bit manipulation but I wonder if I should use something else that would be more appropriate for the Thistlethwaite algorithm.
The issue I'm having is checking if a cube is contained in the sub group G1 <L, R, F, B, U2,D2>
From what I understand, a cube that has correctly orientated edges is contained in this subgroup.
(see https://www.jaapsch.net/puzzles/thistle.htm)
The paper at the end of the page clearly indicates how to check if an edge is good or not but I could not find a way to implement it.
The question I have is: How to check in code if an edge is correctly oriented given a scrambled cube ?
According to the article, page 1:
Getting into G1
An edge piece is BAD if in taking it home an odd
number of quarter-turns of U and D faces is needed; otherwise it is GOOD
A different way of putting this: if you can manage to bring an edge home without ever using a U or D turn (so only turning the L, F, R and B faces), then an edge is good, otherwise it is bad.
So let's say you have a scrambled cube and are looking at one particular edge piece. Identify the position where it should end up (obviously based on the centre pieces). Let's say that one of the two colours of this edge is red. Then identify where the current place of that red face is in the following image:
Do the same for the place where that red side should end up.
If both places have the same colour (yellow or blue) in the above image, then the edge is good. If they have different colours in the above image, then the edge is bad.
You can easily see that if you had taken the other colour side of the edge in question (the not-red one), you would arrive at the same conclusion with this method.
Up to you to translate this to your data structure.
Related
I have to do some image processing but I don't know where to start. My problem is as follows :-
I have a 2D fiber image (attached with this post), in which the fiber edges are denoted by white color and the inside of the fiber is black. I want to choose any black pixel inside the fiber, and travel from it along the length of the fiber. This will involve comparing the contrast with the surrounding pixels and then travelling in the desired direction. My main aim is to find the length of the fiber
So can someone please tell me atleast where to start? I have made a rough algorithm in my mind on how to approach my problem but I don't know even which software/library to use.
Regards
Adi
EDIT1 - Instead of OpenCV, I started using MATLAB since I found it much easier. I applied the Hough Transform and then Houghpeaks function with max no. of peaks = 100 so that all fibers are included. After that I got the following image. How do I find the length now?
EDIT2 - I found a research article on how to calculate length using Hough Transform but I'm not able to implement it in MATLAB. Someone please help
If your images are all as clean as the one you posted, it's quite an easy problem.
The very first technique I'd try is using a Hough Transform to estimate the line parameters, and there is a good implementation of the algorithm in OpenCV. After you have them, you can estimate their length any way you want, based on whatever other constraints you have.
Problem is two-fold as I see it:
1) locate start and end point from your starting position.
2) decide length between start and end points
Since I don't know your input data I assume it's pixel data with a 0..1 data on each pixel representing it's "whiteness".
In order to find end points I would do some kind of WALKER/AI that tries to walk in different locations, knowing original pos and last traversed direction then continuing along that route until "forward arc" is all white. This assumes fiber is somewhat straight (is it?).
Once you got start and end points you can input these into a a* path finding algorithm and give black pixels a low value and white very high. Then find shortest distance between start and end point, that is the length of the fiber.
Kinda hard to give more detail since I have no idea what techniques you gonna use and some example input data.
Assumptions:
-This image can be considered a binary image where there are only 0s(black) and 1s(white).
-all the fibers are straight and their starting and ending points are on borders.
-we can come up with a limit for thickness in fiber(thickness of white lines).
Under these assumptions:
start scanning the image border(start from wherever you want in whichever direction you want...just be consistent) until you encounter with the first white pixel.At this point your program will understand that this is definitely a starting point. By knowing this, you will gather all the white pixels until you reach a certain limit(or a threshold). The idea here is, if there is a fiber,you will get the angle between the fiber and the border the starting point is on...of course the more pixels you get(the inner you get)the surer you will be in the end. This is the trickiest part. after somehow ending up with a line...you need to calculate the angle(basic trigonometry). Since you know the starting point, the width/height of the image and the angle(or cos/sin of those) you will have the exact coordinate of the end point. Be advised...the exactness here is not really what you might have understood because we may(the thing is we will) have calculation errors in cos/sin values. So you need to hold the threshold as long as possible. So your end point will not be a point actually but rather an area indicating possibility that the ending point is somewhere inside that area. The rest is just simple maths.
Obviously you can put too much detail in this method like checking the both white lines that makes the fiber and deciding which one is longer or you can allow some margin for error since those lines will not be straight properly...this is where a conceptual thickness comes to the stage etc.
Programming:
C# has nice stuff and easy for you to use...I'll put some code here...
newBitmap = new Bitmap(openFileDialog1.FileName);
for (int x = 0; x < newBitmap.Width; x++)
{
for (int y = 0; y < newBitmap.Height; y++)
{
Color originalColor = newBitmap.GetPixel(x, y);//gets the pixel value...
//things go here...
}
}
you'll get the image from a openfiledialog and bitmap the image. inside the nested for loop this code scans the image left-to-right however you can change this...
Since you know C++ and C, I would recommend OpenCV
. It is open-source so if you don't trust anyone like me, you won't have a problem ;). Also if you want to use C# like #VictorS. Mentioned I would use EmguCV which is the C# equivilant of OpenCV. Tutorials for OpenCV are included and for EmguCV can be found on their website. Hope this helps!
Download and install the latest version of 3Dslicer,
Load your data and go the the package>EM segmenter without Atlas>
Choose your anatomical tree in 2 different labels, the back one which is your purpose, the white edges.
The choose the whole 2D image as your ROI and click on segment.
Here is the result, I labeled the edges in green and the black area in white
You can modify your tree and change the structures you define.
You can give more samples to your segmentation to make it more accurate.
Ok so, I'm making a 2d dungeon crawler and I want to randomize a map for it. Right now it's look like I'm going to use a Random Walk algoritm for the path, combined with a Perlin Noise for different the underworld enviroments (currently only 1, as I'm using my own shitty looking tile set consisting of only 1 rook image and 1 grass image, but whatever :D)
So in figuring out how random walks work, it looks like I'm supposed to do something along the lines of this:
*create two-dimensional array sized after the map.
*pick random start postion and end postiont (I chose to put these on opposite sides of the map, randomly distributed across its side.
*follow these steps until you hit your finish point:
*pick a direction to 'walk' at random (only up, down, left, right because you otherwise I'm left with diagonal passes which the player can't walk through)
*'walk' that direction for a random amount of steps (I randomize amount of steps first then walk one by one for bound checking later, rather than just drawing a line).
*Everytime you 'walk' on a tile, turn that tile to 1 from originally 0.
*repeat above steps until you hit your finish point.
This leaves me with too much open ground, and too much closed ground. What I'm looking for is a path covered with rooms, sort of, but I want to control how big the 'rooms' become. I don't want 'rooms' to get too big, which some become. So I want the feeling of being in an enclosed space, but also I want to use as much of the map grid as possible.
Is a random walk not suited for this? I was thinking about making every step have a certain width to it, maybe that could work.
Or maybe I'm just implementing it wrong! I'm not a math genious sadly ;P
I am working on a 3x3 three-dimensional box puzzle problem in my homework. I will code with C.
There are 26 boxes and at first, first place is empty. By sliding boxes I must arrange them in correct order. Red numbers shows correct order and 27th place must be empty at last. I do not want you to give me code; I searched in forums and it seems that I must use the A* search algorithm, but how?
Can you give me tips about how I can use the A* algorithm on this problem? What type of data structure should I use?
Define your problem as a states-graph:
G=(V,E) where V=S={(x_1,x_2,...,x_54) | all possible states the 3d board can be in} [each number is representing a single 'square' on the 3d board].
and define E={(v1,v2)| it is possible to move from state v1 to state v2 with a single step} an alternative definition [identical] for E is by using the function successors(v):
For each v in V: successors(v)={all possible boards you can get, with 1 step from v}
You will also need an admissible heuristic function, a pretty good one for this problem can be: h(state)=Sigma(manhattan_distance(x_i)) where i in range [1,54]) basically, it is the summation of manhattan distances for each number from its target.
Now, once we got this data, we can start running A* on the defined graph G, with the defined heuristic. And since our heuristic function is admissible [convince yourself why!], it is guaranteed that the solution A* finds will be optimal, due to admissibility and optimality of A*.
Finding the actual path: A* will end when you develop the target state. [x_i=i in the terms we used earlier]. You will find your path to it by stepping back from the target to the source, using the parent field in each node.
You know how graphs work and how A* finds shortest paths on them, right?
The basic idea is that each configuration of the puzzle can be considered a vertex in a graph and the edges represent the moves (by connecting the configurations before and after the move).
Finding a set of moves that leads from an original configuration to a desired one can be seen as a path finding problem.
I'm coding an abstract strategy game with C# & XNA. As for the AI, I'm currently using Negascout and a depth of 5. The following is the description of the game:
The game consists of a board of 6x7 hexagonal locations, 42 hexagonal tiles, and 6 pieces (1 king & 5 pawns) for each player (max 2 players).
During the first phase of the game, the players alternately place a random tile on an empty location of the board. Each tile can have a maximum of 6 arrows pointing at the edges. Some arrows can be double-pointed. The arrows mean the direction/s of movement from that tile. A double-pointed arrow makes a piece move/jump 2 locations if there's a valid location. The players are not allowed to place tiles in their opponent's row if there are still empty locations left on the board.
Once this phase is complete, the next player in turn places his king on any one of the 6 tiles of the row nearest to him. Next, the movement of the pieces commences. Pieces are moved according to the arrows on the tiles. The game is won by capturing or blocking the king.
Ok, so now to my move generation function.
Tile placement stage
a) Place a tile on the nearest row. The tile is rotated to find the optimal rotation.
b) Once the nearest row is full, place a tile on an empty location that is surrounded by locations on all sides (ie no edge of board). Rotate the tile to find the optimal rotation.
c) If no locations are found, add all remaining empty locations, trying to find the optimal rotation.
King placement stage
a) Locate the location with the best tile and place the king there.
b) Place the remaining pawns on the remaining empty locations on the row.
Movement stage
a) If king is attacked, try to attack the attacking piece if that piece is not defended.
b) Add moves for all player's pieces that are being attacked.
c) Add all opponent pieces that the player can attack.
d) Add all locations player can move to.
Now to the evaluation function.
Tile placement stage
score = No. of tiles current player placed so far + current player's tiles on the nearest row - no. of tiles opponent placed so far - opponent's tiles on the furthest row (nearest to the opponent).
King placement stage
score = current player's tiles on the nearest row - opponent's tiles on the furthest row (nearest to the opponent).
Movement stage
score = current player's pieces' value - opponent's pieces' value.
The weighting of the tiles is 100 for every valid location an arrow points to. The weighting of the pieces is as follows:
piece value = piece type (king = 10000, pawn = 1000) + mobility + defended - attacked - enprise - blocked
where:
mobilty = no. of locations node can move to (free or occupied by the opponent) * 1000
defended = no. of current player pieces surrounding this piece that can actually move to this location * 1000
attacked = no. of opponent pieces surrounding this piece that can actually move to this location * 1000
blocked = (king = -10000, pawn = -1000) piece cannot move because all arrows point to invalid locations and the piece has no chance of moving again in this game.
Quite long, but here come my problems:
When placing tiles, the AI sometimes places a tile using the wrong rotation (ie. places a tile in location where the arrows point to no valid locations). Sometimes this occurs in his 'home' row.
When moving pieces, the AI is ignoring king safety. Moves mostly the king and is captured in about 4-6 moves.
Anybody, especially with chess AI experience, has ideas and suggestions on how to improve my AI, in particular my move generation and evaluation functions?
Thanks
Ivan
btw... If anyone is interested in trying out the mail, just let me know and I'll upload a setup on my website.
Quite long, but here come my problems:
Quite long, indeed.
When placing tiles, the AI sometimes places a tile using the wrong rotation (ie. places a tile in location where the arrows point to no valid locations). Sometimes this occurs in his 'home' row.
In other words, you have a bug in your code. There's no way to answer this question, even with all this extensive preamble. This question should be in a separate, concisely-phrased question that includes a copy of the relevant code.
When moving pieces, the AI is ignoring king safety. Moves mostly the king and is captured in about 4-6 moves.
Same as above. This question can't be answered based on even the extensive preamble you've written.
My advice to you is to be more concise with your questions, post only the details relevant to the problem, and not to combine multiple questions into a single post.
Anybody, especially with chess AI experience, has ideas and suggestions on how to improve my AI, in particular my move generation and evaluation functions?
This is an overly vague question that would normally get closed. If you want some advice about your code, you would have to provide that code in order for anyone to give you a helpful answer that goes beyond blind speculation!
I have to make an application that recognizes inside an black and white image a piece of tetris given by the user. I read the image to analyze into an array.
How can I do something like this using C?
Assuming that you already loaded the images into arrays, what about using regular expressions?
You don't need exact shape matching but approximately, so why not give it a try!
Edit: I downloaded your doc file. You must identify a random pattern among random figures on a 2D array so regex isn't suitable for this problem, lets say that's the bad news. The good news is that your homework is not exactly image processing, and it's much easier.
It's your homework so I won't create the code for you but I can give you directions.
You need a routine that can create a new piece from the original pattern/piece rotated. (note: with piece I mean the 4x4 square - all the cells of it)
You need a routine that checks if a piece matches an area from the 2D image at position x,y - the matching area would have corners (x-2, y-2, x+1, y+1).
You search by checking every image position (x,y) for a match.
Since you must use parallelism you can create 4 threads and assign to each thread a different rotation to search.
You might not want to implement that from scratch (unless required, of course) ... I'd recommend looking for a suitable library. I've heard that OpenCV is good, but never done any work with machine vision myself so I haven't tested it.
Search for connected components (i.e. using depth-first search; you might want to avoid recursion if efficiency is an issue; use your own stack instead). The largest connected component should be your tetris piece. You can then further analyze it (using the shape, the size or some kind of border description)
Looking at the shapes given for tetris pieces in Wikipedia, called "I,J,L,O,S,T,Z", it seems that the ratios of the sides of the bounding box (easy to find given a binary image and C) reveal whether you have I (4:1) or O (1:1); the other shapes are 2:3.
To detect which of the remaining shapes you have (J,L,S,T, or Z), it looks like you could collect the length and position of the shape's edges that fall on the bounding box's edges. Thus, T would show 3 and 1 along the 3-sides, and 1 and 1 along the 2 sides. Keeping track of the positions helps distinguish J from L, S from Z.