I assume you already know about the concept of Min-Max, trees and pruning, heuristic and other basics and what I write here are just some details that might have been underestimated.
I with company a friend wrote our own chess engine sometimes ago. I share some issues and ideas we had and I hope you find them useful.
Since we both were java programmers our language turned our to be java and we started with an object oriented approach. Pieces were objects, board was object, files and ranks (rows and columns in chess literature) were objects. And this was wrong. The overhead was massive and the program was struggling to go further than 2 moves (4 ply) in the search tree.
So with some search we ended up with a brilliant idea (not ours though!): Representing pieces and board as Long integers (64bit). This makes sense because a chess board have 64 squares. The rest was bit wise operations (running very near to cpu = extremely fast). For example, consider a binary 64 bit integer in which the ones are presenting the squares on the board that your piece can attack. Now if you execute a logical "AND" between two numbers like this, a non-zero result states that you have an square with attackers. There are several ways of doing presenting the chess board and pieces, So:
1 - Decide about your Board Presentation
Then you need and opening database. Chess opening is somehow solved ant it is highly recommended to have and opening book. In this case, you have lot's of extra time in blitz games.
2 - Find yourself an opening book.
We did these, but still we were far from being good:
3 - A good chess engine should be able to see 6 moves (12 ply) ahead.
So what we did then, was to use the dead time (if it's a human vs computer engine).
4 - Use the time when opponent is thinking to create some levels of your tree.
And still we were far far away from 12 plies. By more study, we discover some tricks! For example it was suggested to skip one ply of the tree and start from the next ply (like there is no opponent). The idea is that if a move is extremely idiotic, then why to waste the time and see what are the opponents responses to that move. However, one good engine should be able to distinguish between and idiotic move and genius queen sacrifice.
5 - Learn the programming tricks for this specific problem (chess).
Me and my friend, in this state, were still bad :/
What we could do -and we partially did- was to save the calculated positions. If you calculate a position, then save it for future! The same goes for loops in the search tree. The point was to save/retrieve the efficiently:
6 - Save the data you generate...Efficiently!
7 - Code with maximum optimization.
This problem is extremely expensive both in CPU time and memory. It's very important to write your code very efficiently. Remember that we are talking about the branch factor of 35. This means a useless "if" somewhere in your heuristic, can be turn into
3.3792205e+18 useless "if"s somewhere deep in your search tree.
Chess programming is a very very interesting challenge and it's the time that you can put your programming capabilities into a serious test. There are few more points that I can suggest but I'm sure you will discover them by yourself. There many more points that I don't know but you can find them on internet!
Good luck and have fun!