Jump to content
Xtreme .Net Talk

snarfblam

Leaders
  • Posts

    2156
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by snarfblam

  1. Well, as far as the 81 button go, no, putting them on the form in the designer is not the best approach. The biggest problem is that it isn't even slightly dynamic. At the very least, you need to be able to refer to the buttons by their coordinate. Ideally, you want to be able to create as many as you need to let the user select different field sizes, but that's up to you. One other thing I think I should point out is that while you can use buttons, a more typical approach would be to draw the minefield yourself using a set of images that represents each possible state for a single grid square (flagged, empty, with a digit from 1 to 8, ect.). Again, up to you. This isn't really an answer to you question, but a good place to start is with a specification. By writing out a detailed description of how your program is going to work, you make the actual process of coding much, much easier. I don't mean you necessarily have to detail how the program is implemented, but rather how it works from the user's point of view. But you need to be very specific. When you start banging code out (or throwing buttons on a form) before you know exactly what the code is supposed to do, you are bound to run into more problems. A specification would describe what the layout of the application is, exactly what happens when each button is clicked (for every state the button might be in), so on. Every little thing the user might do would be accounted for, and the result must be very well defined. Back to your question, you probably don't want to put any minefield buttons on the form in the designer. Instead, you can create them in code and store them in an array. That way you refer to each button by it's location rather than a name. First you need an array to hold the buttons. I recommend a 2-D array here. [color="Green"]' The comma indicates 2 dimensions, as in x[color="Red"],[/color] y[/color] Dim mineFieldButtons As Button(,) That declares a variable to hold the array, but doesn't create the array. You will need to wait until the user specifies a size if you want to give him that option, but at some point you'll create the array. [color="Green"]' Create our array[/color] mineFieldButtons = [color="Blue"]New Button(width, height) {}[/color] That doesn't give us any buttons, though, just an empty array. So now the important part: use a pair of nested for loops to create the actual buttons. For X As Integer = 0 To Width - 1 For Y As Integer = 0 To Height - 1 [color="Green"]' Create the button[/color] mineFieldButtons(X, Y) = [color="Blue"]CreateButton(X, Y)[/color] [color="Green"]' Add it to the form[/color] Controls.Add(mineFieldButtons(X,Y)) Next Next CreateButton is a function we have yet to define. It will not only create a button, but set its location and size. Function CreateButton(X As Integer, Y As Integer) As Button Dim result As New Button [color="Green"] // Set size // Set location based on X and Y[/color] Return result End Fuction That will get you a grid of buttons, which you can access by coordinate, i.e. mineFieldButtons(gridX, gridY).Text = "BOOM". The problem is you also need to (A) handle the click event for each of them and, (B) in the event handler, figure out which button was clicked. For (A) I recommend you research the AddHandler keyword. For (B), a good approach would be to create a Point object that contains the buttons X and Y, and assign that Point to the button's .Tag property. This would be done in the CreateButton function. Then, in the event handler, you can cast the sender parameter to a button (using CType), get it's .Tag property, cast that to a Point, and then get the X and Y. FYI, I've created a minesweeper clone before and the hardest part wasn't creating the minefield. Figuring out the "flood-fill"-style clearing of mineless spots when the user clicks on a button is much trickier. This is why I recommend the specification. As you write down exactly what happens when the user clicks on a button, you realize that it's a little more complicated than it seems. Then you know what you're in for before you start writing the program.
  2. The first code listing was: byte[] randomData = new byte[deck.Length[b][color="Red"][i]-1[/i][/color][/b]]; The corrected code was byte[] randomData = new byte[deck.Length]; Confusing bounds with length is probably the most common cause of off-by-one errors, which is what it appears PD did.
  3. Re: How to save Graphics Objects to disk as Bitmaps What exactly is the problem? If you are just trying to save a Bitmap, call the Save method of the original Bitmap.
  4. I don't think this is as straightforward as it seems. You need to find or create an algorithm to identify arbitrary insertions and removals from a list. I don't know an algorithm to do this off the top of my head. Here's what I mean. 1: abc abc 2: 123 [color="Red"]987[/color] 3: xyz 123 4: [color="Red"]qwe[/color] 5: xyz How is your program going to tell the difference between: Removing "123" and inserting "987/123/xyz" Inserting "978" and "qwe" separately I'm guessing you'll need to analyze it recursively, i.e. search from the beginning and end of the lists for where a difference begins and ends, and search within the result for where a similarity begins/ends, and search within there to find there a difference would begin/end, ad infinitum (until you find a range the entirely matches or is entirely different). Here's an example. We'll use the two lists above. First we look for a difference. Start at the beginning. Both lists start with "abc." Good. On the next line, line 2 in both lists, we have "123" and "987". Those are different. Now, from the bottom up: the last is "xyz" in both lists. Good. Next one up is "123" in the left list on line 2 and "qwe" in the right list on line 4. Now we know line 2 on the left list is different from lines 2 to 4 on the right list. We can examine these ranges to find a similarity. This is what we now have: [color="Red"]2: 123 987 3: 123 4: qwe[/color] In this case it's obvious what matches, but in a more complicated scenario the match could be buried anywhere within two longer lists. There is where I can't help you because I don't know how to find such a match. I could sit down and try to figure it out, or do lots of research, but I don't know how long that would take and I don't know that I would have any more success than you would doing the same.
  5. I would start by using a for loop. These aren't too different between VB, the syntax is just painfully awkward and the terminating value is usually different by 1. For [color="Blue"]I As Integer[/color] = [color="Green"]0[/color] To [color="Red"]9[/color] Next for([color="Blue"]int i[/color] = [color="Green"]0[/color]; i < [color="Red"]10[/color]; i++) { } // You could also change < 10 to <= 9 A for loop is the best way here. It makes it clear that you want to loop for 1 to 52. Also, FYI, you can use the continue statement to go to the beginning of a loop. This could achieve the same effect as your goto, but we won't be needing this anyway. So we could change your code to: int[] DECK = new int[52]; [color="Green"] //creates an array to hold thegenerated deck[/color] [color="Red"] for(int iCounter = 1; iCounter < 53; iCounter++) {[/color] int rndNum = RandomNumber(0, 52); if (DECK[rndNum] == 0) { DECK[rndNum] = iCounter; iCounter++; } else [color="Green"]// We'll be getting rid of this[/color] [color="Red"]continue; } [/color] return DECK; Now, one problem you have here is that you keep picking random numbers until you find an empty spot. Theoretically, this could potentially take infinitely long. Realistically, it's just gonna take a long time. The method I prefer is to know how many empty spots you have, and pick a random empty spot. For instance, if we have ten empty spots, pick a random number between 0 and 9. Then, you walk through the array counting how many empty spots you pass until you find the one you want. int[] DECK = new int[52]; //creates an array to hold thegenerated deck [color="Green"]// Loop over the values we will insert into the deck[/color] for(int iCounter = 1; iCounter < 53; iCounter++) { [color="Green"]// Determine the # of empty spots and pick a random one[/color] int emptySpots = 53 - i; int insertIndex = RandomNumber(0, emptySpots); int currentLocation = 0; [color="Green"]// Index within DECK[/color] [color="Green"]// Count through empty spots until we find the one we want[/color] for(int emptySpotIndex = 0; emptySpotIndex <= insertIndex; emptySpotIndex++) { [color="Green"]// Find the next empty spot[/color] while(DECK[currentLocation] != 0) {[color="Green"] // Go until we find a zero (empty)[/color] currentLocation++; } } [color="Green"]// currentLocation now points to the nth empty spot, which is where we want to add a value.[/color] DECK[currentLocation] = iCounter; } return DECK; My computer is systematically failing one component at a time, and right now I'm limping along without C# installed, so I haven't tested this code.
  6. Oh... I thought you meant programatically.
  7. It's an interesting question. The thing is, there is no reason that the runtime would ever need this and it isn't a very common need, even when dealing with reflection. As far as I know reflection doesn't directly support that kind of analysis. I'm guessing that what you have is the best you can do: enumerate the types and examine those that derive from the class in question. Is this causing a performance issue? Or were you just looking for a better way?
  8. Right, so what have you got so far?
  9. Well will there be one word different? Could there be two non-adjacent differing words? What happens when we make the following comparisons: I have t[color="Red"]en dollar[/color]s -------- I have t[color="Red"]wenty daffodil[/color]s. Will you match whole words? one [color="red"]two[/color] [u]three[/u] [color="red"]four[/color] five -------- one [color="red"]four[/color] [u]three[/u] [color="Red"]two[/color] five Does your program need to be smart enough to pick out partial matches within a difference? A B C D ---------- [color="red"]B C D[/color] This is why I was asking about a line by line comparison. The two listings here are very similar, but with a line-by-line comparison, no line is a match (A and B, B and C, C and D). These aren't corner cases, these are the most basic aspects of the functionality and they need to be well defined before they can be implemented. That was my point about coming up with a specification for your comparison behavior. It wouldn't be wise to begin coding when you haven't worked out exactly what the code will do. Likewise, I would hate to start giving you some code samples and then have them not do what you need. What are you comparing? Code listings? Encyclopedia articles? I don't know what you have tried here, or if you have ever tried to do any string manipulation or comparison. Or what particular difficulty are you having? I know you are new to C#, but how new are you to programming? I'm not trying to be difficult, but with no background and such an open-ended question it's hard to make useful suggestions. A basic starting point would be to look at the strings one character at a time. Start at the beginning and go through the strings until you find a difference. If you get to the end, they match. If not, remember where the mismatch starts and move on to step two. Begin comparing the strings at their ends, one character at a time and move backwards until you find a difference. Now you know where the difference starts and where it ends. int FindFirstDifferentChar(string A, string B) { [color="green"] // Returns the index of the first different char, or -1 if they are the same [color="Green"] // You can't look past the end of a string, so we will stop at the end of the shorter one[/color] [/color] int shorterStringLen = Math.Min(A.Length, B.Length) [color="green"] // Look for a differing character[/color] for(int CharIndex = 0; CharIndex < shorterStringLen; CharIndex++) { if(A[CharIndex] != B[CharIndex]) return CharIndex; [color="green"]// if two chars don't match, return their index[/color] } [color="green"] // Now, we know that both strings match up to the end of the shorter string. // If they are the same length then they are identical. [/color] if(A.Length == B.Length) return -1; [color="green"]// -1 means no difference[/color] [color="green"] // Otherwise we would consider the extra chars in the longer string // to be a difference [/color] return shorterStringLen; [color="Green"]// Difference starts at end of shorter string[/color] } This would be the first step.
  10. Most optimizations are a trade-off between memory consumption and CPU usage. In this case, it sounds like a great deal. Lose 3 megs of ram for a 1000% performance boost? The fact of the matter is that you want to access this data from the CPU and the GPU and they both have their own memory. You keep carting it from one to the other anyways, and your app is going to have to keep some RAM handy for the temporary data. I'm guessing that loading the same data in both places is going to benefit you in more ways than you expect.
  11. Well, why don't you start by breaking it down. You have a couple of different tasks. First you need to identify the differences, then you need to highlight them. Highlighting them is easy and I'm going to guess you can handle that on your own. (If I'm wrong by all means say so.) The real challenge here, then, is identifying difference. This can be pretty complicated, and the best place to start is to clearly define the expected behavior. Things get tricky if you have different formats. Should different formatting be highlighted? Will you be allowed to compare rich text to plain text? If so, would you want to examine formatting at all? Do you want to do a line-by-line comparison? What are the considerations for character positions? (If a single word is different in the middle of a sentence all following characters will be shifted left or right.) What if we compare these two lines of text: Lazy brown fox Lazy brown dog Should the difference be: Lazy brown [color="Red"]dog[/color] or Lazy brown [color="red"]d[/color]o[color="red"]g[/color] I think the hard part here isn't coming up with the code, but coming up with a clear, precise specification. From there the code should naturally follow.
  12. Couldn't you draw to a separate render target and directly examine the texture data? (I don't know if this offers any performance benefit over simply resolving the backbuffer, but any way you can look directly at the raw data works.) You can just draw the texture directly to the back-buffer to get it onto the screen. This would eliminate the costly DirectX/GDI+ interop. On the whole your approach sounds like an iffy proposition. You're depending on the rendered result to implement other logic. This means that the CPU spins idle while the GPU is working, and then the GPU does the same, idling while the CPU works. I don't know how you are doing your rendering, but I'm guessing there exists an algorithm to do your collision detection without making your application overly "CPU-bound". If you are drawing sprites you could convert your screen coordinates to texture coordinates and examine the texture. If you are drawing geometry then you should be able to do the collision detection with a purely mathematical approach. Shawn Hargreaves has a good article that explains the concept of CPU bound vs. GPU bound programs. The important concept is managing work between the CPU and GPU, and that the less they need to go back and fourth, the better. Ideally the CPU will rarely ever need to hear from the GPU.
  13. This C# snippet shows how to use the WebRequest class to use an HTTP post. I know you're asking about VB, but it's really a matter of knowing which class to use and how to set the properties. You can pick up the important bits from the code listing. If you do have trouble with the translation or if you get stuck on something let us know.
  14. I found How to modify the default Web browser and... using the googles.
  15. Your second method there seems to eliminate the need for a flag at all, but maybe an integer to identify the index of the word that was found, if you really need to cache the results. I was working on the assumption that the list of strings to search for was arbitrary and could be of any length. Even so an inner loop could easily account for a variable length search list. Your algorithm is probably better than mine. I don't know why it didn't occur to me that the lines shouldn't need to be iterated over more than once. Anyhow, algorithmic optimizations are generally the most significant. The methods I suggested represented the same algorithm with different data storage, whereas your better method can probably do the same chore with less memory and less processing, depending on exactly what you are doing.
  16. There are plenty of viable solutions. Here are a few off the top of my head, each of which amounts to tracking which strings have been searched so you can skip them next time. If you are storing the strings in a list-like collection (array, ArrayList, List<T>) you can use a BitArray class the same size as the list. This would use one bit per item to track which strings have been searched. You could also use a collection of structs similar to what I have below. struct stringListItem { public string value; public bool wasSearched; } This couples the related data more closely and might be a little more intuitive to work with, but uses 32 extra bits per string. Still, with 10,000 lines thats only 40k of data, which isn't extraordinary. You could also clone the array and remove strings as they are found (replacing them with null). If you wanted to be more elaborate, you could create a custom collection class that is represented externally by a struct similar to the one above but backed by a string array/list and a BitArray. But I think the best approach would be the simplest and easiest to understand. I wouldn't really worry that much about optimizing unless you actually experience performance issues or excessive memory consumption. The actual bottlenecks in an application often aren't where you expect them to be, and premature optimization often amounts to fixing a problem that doesn't exist.
  17. This behavior doesn't surprise me. If the form is never shown, you probably wont get a Form.Load event since this is called immediately before the form is shown. A lot of initialization gets done the first time a form is shown, and if it is never shown, the normal clean-up probably doesn't need to be performed either, so like Form.Load, Form.Closed probably wont be raised. It seems understandable since you really aren't closing the form, although this isn't immediately obvious if you aren't very familiar with the winforms infrastructure.
  18. Hmmm... I know a lot more about XNA than MDX. Sorry if it seems like a silly question, but does the size of your back buffer match the client size of the output window? It looks like it is scaling the output down with a nearest neighbor interpolation.
  19. Found this solution on Google. You can set the cursor's position using the Cursor class' Position property. For example, this function would move the mouse: [color="Blue"]void[/color] MoveMouse([color="Blue"]int [/color]x, [color="Blue"]int [/color]y) { Cursor.Position = [color="Blue"]new [/color]Point(Cursor.Position.X + x, Cursor.Position.Y + y); }
  20. That shouldn't be too tricky. There's no reason you can't just output multiple files to the same FileStream. Of course, doing it that way you won't gain any compression benefits as far as reduncancy between files, but it really shouldn't make that big of a difference. Also, this wouldn't be compatible with existing formats such as ZIP, but it doesn't sound like you will need it to be so. If you just output multiple compressed files to a single FileStream, the trick is figuring out where one starts and the next ends. You can solve this with a simple header. It can be as simple as a file count, followed by a list of entries that would each consist of the (compressed?) size and location of the sub-file within the containing file (as well as the name, if necessary, and any other info if you need it). Feel free to ask if you get stuck or have trouble getting started.
  21. On my machine, Application.DoEvents works as described. What is it that you are trying to debug? Unless you are testing drawing code in a control you are writing, chances are there is another perfectly acceptable approach. I remember when VB7 came out and we lost edit-and-continue. That, in combination with a new IDE, made it seem impossible to debug. After a while, though, you get used to the changes and work with them. It's not that VB6 debugging is better. DotNet is just a lot different, and a lot better in a lot of ways. It might not seem obvious if you don't understand how drawing controls works in .Net (and most Windows applications). If a control needs to be redrawn (suppose you change the text of a label), it doesn't just redraw immediately. It queues a message that it needs to be redrawn, and when none of your code is running it will process that message. To the user this appears to happen instantly. But when your program is paused, your code can't finish and it holds up the message loop, so the redraw message can't be processed. So the simple answer is no. (Application.DoEvents processes all the messages, which is why it should force a redraw, assuming there is one pending.) VB6 might have managed to get around this, but VB6 uses all kinds of voodoo and dark magic that DotNet doesn't. So you can't do what you want exactly how you want, but if you want us to help you find another way to do what you want and other suggestions haven't helped yet, you can share a little info about what you would like to do and we can probably help.
  22. İ'm not exactly clear on what you mean. Are you saying the IDE is working fine, but the form in your applications stops updating? If so, this is normal and expected. If VB6 did any differently, that concerns me. While your application is paused (whether you hit a breakpoint, click the pause button, or step through code) no code in your application is running. That means it can't update or draw itself. That can be inconvinient when you want to see changes in your application reflected in the UI, but if the UI kept handling messages there would be potential for all sorts of problems. You don't want code running behind your back while you are debugging. Imagine a control that changes some data in its drawing code. Now imagine trying to debug some separate code that also deals with that data. I wouldn't like it very much if the value of variables kept magically changing on me while I was stepping through code. Or, imagine trying to debug your drawing code. If you want the form to redraw itself while the application is paused, you can call Application.DoEvents in the Immediate window. The problem is your form needs to be visible when you do this. If you have multiple monitors this is easy, but if not you would need to de-maximize the IDE and cram both your form and Visual Studio on the screen.
  23. You mean when it is inside your application's window? System.Windows.Forms.Cursor.Hide(); Hide() is a static method on the Cursor class. This code will hide the cursor within your application, presumably for all windows in the application. Call Cursor.Show() to display it again.
  24. Personally, my preferred method is to store a copy of the original document (in memory) and compare it to the current version of the document. You might find yourself in a situation where the document might be larger that something you would like to keep in RAM. In that case you could consider storing a hash of the original document and comparing it to a hash of the current document. PD is right, though. In this simple case, your method should work fine. In some situations there may be many places in the UI where the document can be modified in different ways. Being able to compare to the saved version of the document seems to cover all bases.
×
×
  • Create New...