|
Please, when you post code that has < and > characters in it, either manually replace them with < and >, use a program that will do it for you, or check the Display this message as-is (no HTML) checkbox when posting. It's very hard to read otherwise. Using the <pre> tag around your code (for indentation) would also be nice.
Ok, here's one problem:
void MarkHTMLSignificance( CString& strLine )
{
...
TCHAR* pszResult = strNewLine.GetBuffer( nLen * 8 );
...
InsertCode( pszResult, g_szBeginTitle, bLineChanged );
...
}
void InsertCode( TCHAR*& pszBuffer, TCHAR* pszKeyWord, bool& bLineChanged )
{
...
while (*pszBuffer != '\0' && *pszKeyWord != '\0' )
...
}
A buffer is allocated, but no initialization other than copying in the original string is performed. Looking for a NULL terminator is not a good idea; you should instead pass in a length count, and check using that.
I should also probably mention the CString::Replace() method...
farewell goodnight last one out turn out the lights Smashing Pumpkins, Tales of a Scorched Earth
|
|
|
|
|
Okay, I fixed the display of the message... thanks
But see, I don't to replace anything, I just want to insert
some characters at a specified place. And I want to go fast, cause
I have to process a lot of text, so that's why I'm trying to use
pointers instead of CString operations. And it works fine in debug
mode, that is what is killing me.
I even tried turning off all release mode optimizations, and still
nothing!
Even if I set strNewLine to "", that does not make any difference.
Its like the release mode version doesn't like the fact that I'm
passing a TCHAR* by reference to InsertCode. But why?
Sigh... I was hoping to have this program done by Monday, but
its not looking good because of this... :P
Thanks for any more thoughts ....
|
|
|
|
|
Well, your desire for speed is certainly understandable. But it might be best to start out writing code that works, and then optimize it.
Anyway, as i said above: i doubt the CString buffer is being initialized. This means that in debug mode, it will contain 0xdbdbdbdb (or some such filler meant to identify uninialized memory) but in release, it might be anything.
Do the following:
get rid of this line
if ( pszBuffer )
in this line, get rid of the bold part
while (*pszBuffer != '\0' && *pszKeyWord != '\0' )
You'll then be rather unsafe, but the program should work if i'm right. A correct solution would be to pass in the length of the buffer.
farewell goodnight last one out turn out the lights Smashing Pumpkins, Tales of a Scorched Earth
|
|
|
|
|
You are a genius. That actually worked. I can't believe it.
That is pretty weird.
I'm stunned because I thought that and have always heard that
CStrings were initialized to empty in their constructor.
But I mean, if I do this
CString strLine;
or
CString strLine = "";
Shouldn't the string be initalized to an empty string???
Hmmm...
-Julie
|
|
|
|
|
I still don't understand why that works:
void MyFunct( LPCTSTR& pszBuffer )
{
if ( pszBuffer )
do_something();
}
...
CString strLine;
LPCTSTR szBuffer = strLine.GetBuffer( 100 );
MyFunct( szBuffer )
....
How could szBuffer be null in release mode? If its pointing to strLine's
buffer, its definitely pointing to something non-null.
why does this work?
I'm mystified..
Thanks,
-Julie
|
|
|
|
|
Life is Full of Suprises
VC++ in debug mode assignes non-NULL values to newly allocated memory as a debug helper. This explains why it works in debug.
pszBuffer should not be NULL. I'm not sure why i told you to get rid of the line that checked for that. (not sure why i'm still on CP at 12:30AM either... great, another addiction)
However, the data pointed to by pszBuffer might easily be NULL. Especially the first character, since this would be the NULL terminator on an emtpy string. Internally, CString s maintain a length counter, so the actual databuffer can be any size. The NULL terminator is strictly for the convenience of C-style string handling routines that need to access the CString . Keep in mind how the standard C library functions work: strcpy() does not require a length specifier, but is a danger spot for buffer overruns if you are not careful, since it does not (and cannot) check that the destination buffer is large enough to hold the source string. strncpy() does require a length specifier, and uses that to operate safely.
This is why using a string class instead of raw C-style strings is nice; constantly having to make your code aware of the total size of buffers gets old in a hurry.
Anyway, sorry you have to be working on the weekend; good luck on your project!
farewell goodnight last one out turn out the lights Smashing Pumpkins, Tales of a Scorched Earth
|
|
|
|
|
Thanks, you have totally saved my life. I was full-on panicking
earlier this evening. whew!
|
|
|
|
|
I think I get it.
The content of the pointer could be anything, as you said.
Even though I said I wanted to allocate a certain amount
for a buffer using GetBuffer, the contents of the buffer
could be anything - including '\0', but it wouldn't be a '\0'
that I had asked for or put in there. It would just be random
memory. Oh jeez. weird. ok.
Thanks again,
-Julie
|
|
|
|
|
Hello,
I have a subclass from CDialogBar. I try tu put a IP control in it, but i can´t get the bytes in that control.
I see that happens not only with this control, it happens with any control that don´t be a edit...
What happens?
Thanks Codeprojects...
UI
|
|
|
|
|
Can you post some code? I've used CDialogBars quite a bit, and have never experienced the problems you are talking about.
------------------------
Derek Waters
derek@lj-oz.com
|
|
|
|
|
Hi everyone. I have some code which centers a series of buttons on a dialog, which is in OnSize(). Problem I have is, as the user resizes the control, the buttons are drawn twice (?), and there are "artifacts" of the original draw are still there. If the window is minimized and brought back up again, the buttons draw properly and the "artifacts" are gone. The buttons do center and adjust properly as the window is resized, but leave those "artifacts" for some reason. It doesn't happen when the window is maximized and normalized, but do occur when the user drags the window frame and resizes that way.
I am also using Paul Wendt's CControlPos class which is found on Codeproject, which moves all the other controls (I had to move the buttons manually to achieve the centering with a series of buttons).
Anyone have any ideas? Any help is greatly appreciated!
<br />
void CDlgMain::OnSize(UINT nType, int cx, int cy) <br />
{<br />
CDialog::OnSize(nType, cx, cy);<br />
<br />
CRect rcButtonRect;<br />
<br />
if(::IsWindow(GetDlgItem(IDC_BTN_ADD)->GetSafeHwnd()))<br />
{<br />
<br />
bool bDrawAgain = true;<br />
<br />
GetDlgItem(IDC_BTN_ADD)->MoveWindow(rcButtonRect, bDrawAgain);<br />
<br />
rcButtonRect.left = ((cx - iParentWidth)/2) + iButtonLeft;<br />
rcButtonRect.right = rcButtonRect.left + iButtonWidth;<br />
GetDlgItem(IDC_BTN_EDIT)->MoveWindow(rcButtonRect, bDrawAgain);<br />
<br />
rcButtonRect.left = ((cx - iParentWidth)/2) + iButtonLeft;<br />
rcButtonRect.right = rcButtonRect.left + iButtonWidth;<br />
GetDlgItem(IDC_BTN_DELETE)->MoveWindow(rcButtonRect, bDrawAgain);<br />
<br />
iButtonLeft = 391;<br />
rcButtonRect.left = ((cx - iParentWidth)/2) + iButtonLeft;<br />
rcButtonRect.right = rcButtonRect.left + iButtonWidth;<br />
GetDlgItem(IDC_BTN_COPY)->MoveWindow(rcButtonRect, bDrawAgain);<br />
}<br />
<br />
m_cControlPos.MoveControls();<br />
}<br />
|
|
|
|
|
Is WS_CLIPCHILDREN set for the dialog?
Maybe calling CDialog::OnSize(nType, cx, cy); after moving the controls would work.
farewell goodnight last one out turn out the lights Smashing Pumpkins, Tales of a Scorched Earth
|
|
|
|
|
I tried doing both, with no luck It still leaves junk behind when the user drags on the window frame
|
|
|
|
|
well, you could also pass in FALSE to all the MoveWindow() calls, then follow everything with Invalidate(TRUE) . It'll flicker a bit, but should look ok.
farewell goodnight last one out turn out the lights Smashing Pumpkins, Tales of a Scorched Earth
|
|
|
|
|
I've also seen this problem when resizing static picture controls (eg: frame borders). Try invalidating and updating the dialog at the end of the repositioning.
void CDlgMain::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
....
Invalidate();
UpdateWindow();
} /ravi
"There is always one more bug..."
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
That worked great! Thanks for the help!
|
|
|
|
|
i am trying to write a tictactoe game in VC++ but i dont know how to organize it and whats the best way to do it. i am planing to use Bitmap graphics and beneath it use a grid to find out which one the user clicks. and i am planing to use recursion to implement it but i dont know if thats the efficient way to do it. can anyone help me. i am not good in designing? can someone give me an advice on whats the best way to do it?
|
|
|
|
|
This is your homework, isn't it.
Here's what i'd do to get started:
use the VS wizards to create a dialog based app. Delete all controls from the dialog. Implement an OnPaint() handler that draws your board. Handle mouse messages to respond to player actions. Use a separate class to implement game logic.
There are many ways to implement a tic-tak-toe game; just use whatever makes the most sense to you. If you have a specific question, i'm sure you'll get plenty of answers to it.
Have Fun!
farewell goodnight last one out turn out the lights Smashing Pumpkins, Tales of a Scorched Earth
|
|
|
|
|
I did this for my Gr. 12 comp sci course last year, but in VB...
It is your homework...
In anycase. This is what I did.
1) Create a dialog
2) Create (an array or not) of 9 Pushbutton controls and set the font accordingly, I used Arial Bold 23 Pts. This will let you focus on game logic, instead of x and o drawing.
3) Last create an array of 9 chars, NULL=Empty, X is X, Y is Y. This array will map to your physical buttons. this way you can disable the button once it was clicked and avoid having to double check the array to ensure someone hasn't chosen the same location twice.
4) On each buttonclick set the coresponding array element to X or Y depending on whos turn it is, then change the current buttons caption to the current elements value.
5) Design a killer AI, that of which will rival a Russian chess champion.
Tips: It'll be much easier to create the buttons statically and position them with dialog editor.
Tips: Each button click do the following!
1) Iterate array looking for X or O's horizontally
2) Iterate array looking for X or O's vertically
3) Iterate array looking for X or O's diagonally
If your test function returns TRUE you know someone has won the game!
BOOL IsWin()...???
your choice...from here on your on yer own...
Cheers!
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
Yah, i made my design using MFC. i used the CDC function moveto and line to draw the board. beneath it i made an array of Crect so i would know which one i clicked. if i click a point inside a rectangle an X will be draw using the textout function. pretty much, i got all the designing done, my only problem now is creating the AI for my tictactoe. i am thinking of using recursion to implement that. i dont know if that is efficient or just make a list of moves instead. is using recursion better? honestly this is not my homework. in school where learning assembly but i thought id practice MFC and C++.
|
|
|
|
|
You're learning assembly in school ? Cool.
The most interesting and effective way I can think of would be to program the computer to play itself and remember moves that lead to a win, as well as obviously searching for the ability to finish a row. That way it will teach itself.
Sorry, I really have only vague ideas about how to do this.
Christian
I have come to clean zee pooollll. - Michael Martin Dec 30, 2001
Picture the daffodil. And while you do that, I'll be over here going through your stuff.
|
|
|
|
|
A tic-tac-toe AI alogorithm is quite similar to a Chess AI except much simpler. There are numerous ways to implement it, and recursion is certainly an escellent bet IMHO.
Work around a frameowrk similar to this;
For each player move:
1. Determine possible computer moves
2. For each computer move, guess the player move. Let the computer mentally play the game until a given recursion limit (e.g. 6 moves) is reached.
3. For each series, return a score for that path of play.
4. Collate the data, and the highest scoring move-set wins, and the move is made.
Optimisations can be made, such as after the move tree has been compiled, if the player makes the predicted move, just chop off the inappropriate branches and iterate another level. This is quite a complex optimisation if you are only starting out, but will probably be worthwhile if you want to go that far.
Remember, if the board is empty, and you are playing on a 3x3 grid, there are 3x3 possible moves, i.e. 9 moves. However, once the computer has moved (presuming the computer were to take first play), there will be eight remaining moves for the player. Bearing in mind that the computer will have to guess the player's moves as well as it's own, that means that, if you take to recusion to 6 levels, there are 9P6 possible moves, (i.e. 9x8x7x6x5x4 moves). For a full game, there would be 9! possible moves, i.e. 362,880 possible moves, so you probably wouldn't want to guess out the entire game.
OK - moving away from the actual calculations that have to be done, how would you store this data. If you were to use a tree structure, each node in the tree would need the move data (i.e. X and Y co-ords), a pointer to the next sibling node, a pointer to it's first child node and possible a parent-node pointer. Hence, you would need something like;
class CMoveNode {
public:
CMoveNode() {}
~CMoveNode() {}
BYTE m_XMove;
BYTE m_YMove;
CMoveNode *m_pNextSibling;
CMoveNode *m_pFirstChild;
CMoveNode *m_pParent;
private:
}; So, all in all a maximum of about (presuming 32-bit pointers), 3*32 + 2*8 = 96 + 16 = 112 bits per node = 14 bytes.
If you were to take the system to 4 levels deep, you'd have as a worst case scenario 9P4 nodes = 3024 nodes, * 14 = ~42K.
Hope that's useful, it's not something I've done before but I've read up on things like this. I don't proclaim to be an expert, but would also be interested to hear yours and others comments on these ideas. Maybe you could do an article when you've finished .
--
Andrew.
|
|
|
|
|
I'm pretty sure recursion for a function with as much code as AI would be over kill.
char gameBoard[9] = {0,0,0,
0,0,0,
0,0,0};
BOOL IsWin() const
{
char Piece = 'X';
...BEGIN loop
if(gameBoard[0] == Piece && gameBoard[1] == Piece && gameBoard[2] == Piece) return TRUE;
if(gameBoard[3] == Piece && gameBoard[4] == Piece && gameBoard[5] == Piece) return TRUE;
if(gameBoard[6] == Piece && gameBoard[7] == Piece && gameBoard[8] == Piece) return TRUE;
...
...
Piece = 'Y';
...END loop
return FALSE;
}
This is something like what I did
Cheers
"An expert is someone who has made all the mistakes in his or her field" - Niels Bohr
|
|
|
|
|
hey thank for the help... shoq, andrew, christian and hockeydude. well, i think its not gonna be an over kill to use recursion because i am only implementing a Tictactoe board. so theres only 9 possible moves. but i think ill try do both recursion and the list idea. for recursion, ill make moves made and if the board is all occupied as my base case. as the general case it will just continue look at at possible moves - the moves done. for the list idea. ill try to immitate the deep blue idea by making a list of all the moves and putting it on a List or a stack. after i finish this ill try show you guys what i came up with...
|
|
|
|
|
if u did the tic tac toe in trees can u send it to me coz i wanna know how to do it in recursion. Hisham86@aucegypt.edu this my e-mail
thanks,
|
|
|
|
|