Multi-Threading for a Heuristics Connect 4

# Multi-Threading for a Heuristics Connect 4

• 2. srpna 2012 7:02

I've been searching the web for about 5 hrs now and found some things similar to what I am looking to do, but nothing is working. I am working on a Connect 4 game using heuristics, machine learning, and machine learning with heuristics. With a 6 (rows) x 7 (columns) board, heuristics looks at each possible move for the current player (maximum of 7 moves).

Here is some of the code...

```namespace Connect4
{
public enum eSquare{ NONE, RED, WHITE }

public class Position
{
public int Row { get; private set; }
public int Col { get; private set; }

public Position( int row, int col )
{
Row = row;
Col = col;
}

// some other non-important code ...

}

public class HeuristicValue
{
private Position _pt;
private eSquare[,] _mBoard;
public decimal Value { get; private set; } // value I want to get after the thread is done processing

public HeuristicValue( Position pt, eSquare[,] mBoard)
{
_pt = pt;
_mBoard = mBoard;
}

public void GetHeuristicValue()
{
decimal hValue = 0M;
bool redTurn = IsRedTurn( _mBoard ); // basis redTurn on red vs white count. // returns true if red.Count = white.Count, false if red.Count > white.Count

_mBoard[ _pt.Row, _pt.Col ] = ( redTurn ? eSquare.RED : eSquare.WHITE ); // temporary move

for ( int row = 0; row < 6; row++ )
for ( int col = 0; col < 7; col++ )
{
if ( row < 3 )
{
hValue += CalculateHValue ( parameters here ); // checks horizontals

if ( col < 4 )
hValue += CalculateHValue( parameters here ); // checks top left to bottom right diagonals
}

if ( col < 4 )
{
hValue += CalculateHValue ( parameters here ); // checks verticals

if ( row > 2 )
hValue += CalculateHValue( parameters here ); // checks bottom left to top right diagonals
}
}

mBoard[ _pt.Row, _pt.Col ] = eSquare.NONE; // remove temporary move

Value = hValue;
}
}
}```

I know this code is not "thread-safe". If possible, I would like to have 7 threads running to get the heuristic value for each possible move. I would also like to have the heuristics look 4 or 5 moves ahead. With the programming I have now, looking 8 moves ahead takes approximately 30 minutes to make the first move. So, I figured maybe possibly threading moves. Would this be a reasonable approach? And if so, how would I keep my values from interfering with each other?

My current outcome with threading gives correct values most of the time.

For example, first move heuristics are supposed to show...

Position | Value

{5, 0} | 3

{5, 1} | 4

{5, 2} | 5

{5, 3} | 7

{5, 4} | 5

{5, 5} | 4

{5, 6} | 3

Whereas, every now and then I get...{5, 0} = -4 and {5, 1} = -1.

I know it has something to do with the sharing of the variables, but I can't pinpoint how to make each thread have it's own instance of the variable "decimal Value".

Don't fix what ain't broken...just tweak it a little

### Všechny reakce

• 6. srpna 2012 2:54

Have you thought about using a recursive method to check for patterns versus analysing every row/col? I may be reading your code wrong, but off the top of my head that would speed things up. A class running a pattern check only as far as it would require (to any piece connecting) would check each direction only as far as required versus built. You would then have the option to run this check against the 2nd players pieces and find overlaping open choices. Rank the choices based on their level of completion towards 4 in a row completion. Something like that. If your interested I could write up an example. Let me know =)

Note: You could also add a property to the "gamePiece" class (what I would call it versus position class), that would store whether or not it was a piece that is still in play for analysing your next move. If its a piece buried and can no longer connect, there is no reason to check it again.

May the Force be with you young Jedi...

`Console.WriteLine("-Warren");`

If you find someone's post helpful please click the green "up arrow" to the left and vote!
It's Greatly Appreciated =)

• 6. srpna 2012 3:08

I am always open to suggestions. I think I know what you are talking about using a recursive method, but I have been known to be wrong at least once in my life :). And by looking at my code, I noticed that my "// check horizontals" and "// check verticals" are swapped.

Although, finding the checkers of the specific player and just find the direction of play. The positions are stored in the Machine Learning's list<Position> so I wouldn't have to loop through the board to find them. Is that what you may be talking about, or something different?

I basically got the code from a Tic-Tac-Toe game where it checks through the entire board for positions. And now that I think about it, with Tic-Tac-Toe, you can place anywhere. Where, with connect 4, you can only place on the next row available. So looping through the whole board from the first move would be not so much a smart thing to do!

Don't fix what ain't broken...just tweak it a little

• 6. srpna 2012 3:55

Very true, tic-tac-toe is a very small board and that makes it easy to check. I think with connect 4 your going to want to check a few things in the whole process of playing.

Well I noticed you started to create an object for each checker piece in play correct? If so you have the position already, so using a recursive method we could feed it a piece to check against, which it then looks for surrounding pieces and calls itself again passing the surrounding piece. For each time it calls itself we could count how many pieces have been found in a row in a specific direction. Example: if the first piece checked found a friendly piece to the top left, then only increase the counter for checks that continue following that pattern (direction). If we change directions it would call itself with a new counter (unless opposite of the direction we started counting).

Long story short we check for patterns being played versus checking the board. We pretty much ignore the board, accept we would have to keep a tally of where piece has been played during creation of checkerpiece objects (so that we don't ever create a duplicate).

The learning part would come during the choice of each play. I would think you would play each pattern to completion or end (blocked by the other player) and compare the two patterns that were in play. Your going to want to build some type of reward system so that the further a play gets prior to getting blocked or winning the more likely you would want to repeat that pattern in another game (based on the way the other player has made his choices).

I Hope that makes sense... I'm kind of tired and I'm just throwing ideas out there. I'm about to call it a night so I may be more helpful in the morning. I'll post back tomorrow, Gnight.

May the Force be with you young Jedi...

`Console.WriteLine("-Warren");`

If you find someone's post helpful please click the green "up arrow" to the left and vote!
It's Greatly Appreciated =)

• 6. srpna 2012 4:08

Thanks for the input so far. Yes, each checker is it's own object. As of now, I have all of the heuristic values and learning already done. At the end of the game, it adds/subtracts values according to win/loss/draw. I was just looking for a way to speed up the process on which it calculates, which, from what you are saying makes sense. I guess I just needed new eyes on it as I have been racking my brains out trying to figure it out :).

The heuristic values are as follows...

If player has 1 in a row, add 1

If player has 2 in a row, add 10

If player has 3 in a row, add 100

If player has 4 in a row, add 1000

If opponent has 1 in a row, subtract 2

If opponent has 2 in a row, subtract 20

If opponent has 3 in a row, subtract 200

If opponent has 4 in a row, subtract 2000

For the learning, if player wins, add 3 to all moves made during the game according to the configuration of the board at the time; if loss, subtract 6; if draw, red subtracts 2 while white adds 1 (only because white's perfect game can only tie if red plays a perfect game).

Thanks, and let me know what you think.

Don't fix what ain't broken...just tweak it a little

• 7. srpna 2012 3:01

So, I've been thinking about this throughout the day (sorry for the late response it's been a busy day). Are you planning for the computer to learn to repeat the whole game if it wins? or learn to mix different patterns to win based on each pattern the opponent plays?

Can you tell me a little bit more on how your learning process works? Also are you attempting to have it learn, or play out a portion of the game everytime it makes a move? or both?

May the Force be with you young Jedi...

`Console.WriteLine("-Warren");`

If you find someone's post helpful please click the green "up arrow" to the left and vote!
It's Greatly Appreciated =)

• 7. srpna 2012 3:03

Do you by chance have a set of user stories for the whole process? acceptance details and how you meet them? Or something similar?

May the Force be with you young Jedi...

`Console.WriteLine("-Warren");`

If you find someone's post helpful please click the green "up arrow" to the left and vote!
It's Greatly Appreciated =)

• 7. srpna 2012 3:55

Thing is, both sides (white and red) both learn at the end of the game according to the moves they made, either heuristically, learning, or human play. Got the idea from a book that I got while in schooling. It gave the code for tic-tac-toe, so I decided to implement it into a connect 4 game. If red wins, it tries to replay the winning moves, but at the same time...white lost with those moves, so it will try a different route. I'm not really that advanced in the whole process of programming a game with heuristics, but I figured it would be a good start for learning :) What do you mean by having a set of user stories and acceptance details? Not familiar with that terminology.

Don't fix what ain't broken...just tweak it a little

• 7. srpna 2012 4:20

One other thing I hadn't thought about till now, is that a "mirror" image is slowing down the process. Too many things going through my brain at once. I can't think anymore lol.

Don't fix what ain't broken...just tweak it a little

• 7. srpna 2012 5:01

Users stories are a way to begin mapping out the process of an automation solution for an end goal. The format is like so:

As a <type of user> I want <a goal> so that <reason>

From my understanding you want to start off with an "epic" story which matches your end goal. By "epic" I mean a story that may explain an ending but doesn't really tell you how you will get to that ending; a story that must be broken down.

While this initial story may not seem to be very useful in the beginning, it helps us as humans stay on track with breaking down the process. Our brains like to "connect the dots" and find it easier building a path to a forseen ending, versus make up a path to an unknown ending.

Example: As a computer player I want to beat another player in connect4, so that i can win.

Ok so that doesn't seem very helpful, but lets take a look at that story and see if we can break it down further by figuring out what goals we need in order to make that story happen.

Well in order to beat another player in connect4 we need to know how to play it, so how about:

Example: As a computer player I want to get 4 checker pieces in a row, so that I can beat another player.

Well there is still more to this then getting 4 checkers in a row in order to win, we need to also keep an eye out for the opponent, and make sure that player doesn't connect4 before the computer.

So how about: As a computer player I want to monitor the other players checker placement, so that I can stop that player from getting 4 in a row.

Do you see how this User Story template is helping us build a roadmap to the requirements of building the application?

By starting at the end, and working your way to the top you can easily think of more and more requirements to learn, play and win the game. Once you can think of all that is required to meet our original goal, you will almost have the whole process written out, and that makes writing the code so much easier.

Of course you don't have to do that, but when I first found this template and applied it to an application I thought I had completed, it helped me find a lot of things I didn't even know were required, as well as additional processes that helped me reach my goal in a better way.

Like the Samurai we too can learn to focus all skill into one area as it is required, you do not want to have "too many mind" when facing an enemy in battle, you do not want to focus on others such as your loved ones, you want to focus on one thing -the fight.

One of the reasons I think this works so well is that it keeps us focused in one area at a time. Another thing human beings are surprisingly not good at is multi-tasking. Like computers we can do one thing at a time switching back and forth simulating the act of multi-tasking, but unlike computers we do not tend to hold on to all of the tasks properly when going back and forth; so we forget things. We get focused on writing code instead of thinking about the process, or thinking about the process and not having the ability to focus on the syntax required to bring that process to life. With "User stories" we focus only on the process required, we map it out quickly and then put our focus on the tasks required to make those stories happen, then we focus on coding.

Sorry if I got a little off track or to deep into the whole "User Story" template, I have just found it very helpful in building a more sound solution.

If you want a fresh look at the whole process, try to take a step back from all the code you've already completed (I know that is difficult since I'm sure you've already spent a lot of time on it) and try to think of that epic story, and give yourself around an hour; see if you can break that story down, further and further; if you start slaming out additional stories going past that hour just let it happen. If by the end of that hour you have are done, try to think of the tasks required to make those stories work. After that if you like where this is heading, see if you can utilize code already written and maybe just reorganize it a little (you might already be on the right track, and just need a little more order to finish it). That is if your interested in trying that process out.

There I go again, babbling on... It's been a long day, I'll chat with you tomorrow. Gnight.

May the Force be with you young Jedi...

`Console.WriteLine("-Warren");`

If you find someone's post helpful please click the green "up arrow" to the left and vote!
It's Greatly Appreciated =)

• Upravený 7. srpna 2012 5:02 fixed one of many spelling errors
•
• 7. srpna 2012 5:17

lol...not babbling...good stuff. I get the initial "I want to..." and then "darn...start over". I think I've rewritten this code like 3 times already...each time getting more information in between the lines for better performance or better coding strategies. I'm kind of a code-as-you-go...mainly because I have to "see" what I am working with in order to code it. I get side-tracked if I try to initially "think" ahead of what I want to do.

See, when I located the tic-tac-toe, 3 of the case studies were "Create a Connect 4 Human vs. Human, Heuristics vs. Human, and Heuristics vs. Learning". So for 2 years, I tried to program the Human vs. Human with no luck until a couple of months ago when I started getting more into the programming. Then I figured, if I can take some of the code from the tic-tac-toe and implement it, I could get a heuristics connect 4. Then I took some of the code for the learning process.

As well as the game works with just looking 1 move ahead, I just wanted to see if I could make it look 5 or 6 moves ahead. It just keeps setting me back as it takes so long for the first 10 moves. Once a column fills up with checkers, it takes about 10 seconds to make the next move. When another column fills up, it takes about 4 seconds, then about 2 seconds, until it just starts moving like you can't follow it (of course, I have timers set at intervals of about 500ms to see this). Now, since I've started to try threading, my code is just all over the place :D.

So, in the end, I'll prolly just keep what I have with only looking 2 or 3 moves ahead or re-writing again lol. Oh, and I do have a couple of "block player" methods, but they don't work so well....yet. Still need to figure out point scoring for that. I think I have an idea, but not sure yet. I'll have to play around with it.

Don't fix what ain't broken...just tweak it a little

• 7. srpna 2012 5:30

One of the major things I had to deal with is the board configurations. These numbers are so high (can't use them in an array or list), I have to write the token values for learning to file and then read from file when determining what move to make. I probably should have mentioned that earlier but forgot about it. I know that it takes time to go through the file looking for the current board configuration and if it doesn't exist, it creates it.

I can write it to where it is really fast on reading the values if I put the values in a "board configuration #" file, such as "304952.token", but with all of the files that will be inhabiting the folder, it's a massive hard drive hog vs putting all the board configuration values in 1 file, such as "tokens.c4t" and looping through until it finds the correct one, then split the line and read the values. These configurations get into the hundreds of quintillions (3^42)...109,418,989,131,512,359,209 configurations. No array or list can handle that many indexes (integers only). Whereas tic-tac-toe only needs tens of thousands (3^9)...19683 configurations. The configurations of Connect 4 can seem a little overwhelming, even if cutting it in half for mirror image. Almost to the point of...is it even worth messing with? Either way, it's a fun endeavor!

Don't fix what ain't broken...just tweak it a little

• 8. srpna 2012 2:33

I can't help but wonder if there is another way to handle the learning portion of this game, and I would really try to give the planning process a chance; it might really shed some light on your requirements. When you try to write out a user story, try to place your self in the role of the user; which in this case is a Connect4 player, the computer. As a computer player I want to learn what pattern is best to play so that I can beat my opponent. Well in order to break that down we could say, as a computer player I want to walk through each pattern in play to include the opponents open moves so that I can learn how to counter act his/her moves.

Again this is just an idea being thrown out there, it may be good it may be bad, but don't be afraid to throw them all out there in the open. Once you've emptied your mind completely then sort out the good ideas from the bad.

If at all possible you need a system that doesn't have to reference a log file. Atleast if you must load so much data maybe look into serializing a collection of objects/data into a binary file(s), and have the whole file loaded as needed during certain portions of the gameplay. Maybe store each possible pattern from a given spot, and only load that data if its something that could be played off. With the kind of lag your dealing with it almost sounds like your accessing the files for each check against the data. If you were to serialize and load the data into memory it would really cut down the access time.

May the Force be with you young Jedi...

`Console.WriteLine("-Warren");`

If you find someone's post helpful please click the green "up arrow" to the left and vote!
It's Greatly Appreciated =)

• 8. srpna 2012 2:40

If you have never tried it, this site has a good tutorial on serializing objects.

Serialize Tutorial

May the Force be with you young Jedi...

`Console.WriteLine("-Warren");`

If you find someone's post helpful please click the green "up arrow" to the left and vote!
It's Greatly Appreciated =)

• 8. srpna 2012 5:07

As a computer player I want to learn what pattern is best to play so that I can beat my opponent. Well in order to break that down we could say, as a computer player I want to walk through each pattern in play to include the opponents open moves so that I can learn how to counter act his/her moves.

That's where the heuristics come in at. The learning process deals with the maximum possible moves (most of the time 7, until one of the columns fill up) of the given player. With the heuristic value, if the computer has not played that position yet, it gives it an additional 42 points (default token value).

For example, with the first move, the heuristics would show...

| 3 | 4 | 5 | 7 | 5 | 4 | 3 |

The way it calculates these numbers is...If I place my checker in the 1st column, I have 1 checker in a vertical, diagonal, and horizontal row. If I place my checker in the 2nd column, I have 1 checker in a vertical and diagonal row, but also in 2 horizontal rows ({5,0} - {5,4}) and ({5,1} - {5,5}) {row, column}. And so on.

Since I haven't moved in any of these places yet, I have the values of | 45 | 46 | 47 | 49 | 47 | 46 | 45 |. In that case, since 49 is the highest value, I will take the center column. After the game is over, since I lost, my first move was to the center. So I will subtract 6 from the 42 and any other tokens for the moves that I have made during the game.

So now my first move values will be | 45 | 46 | 47 | 43 | 47 | 46 | 45 | (heuristic + learning) ... | 42 | 42 | 42 | 36 | 42 | 42 | 42 | (learning). So my first move next game will not be in the center but in either columns 2 or 4.

Token values are never less than 0 but heuristic values can reach up to -12000 (I think). Maybe more, maybe less. The token values are just for the learning process of the games played (whether it will try to replay that same game (win) or try a different route (loss/draw)). If the heuristics come in at a very low negative, it shows a REALLY BAD move if it were to move into that position (possible win for the opponent). If it comes in at a very high positive, it shows a REALLY GOOD move if it were to move into that position (possible win/block for the player).

This is why I am mixing both the learning and heuristics together. I would really like to try and get the threading to work so that instead of waiting on the 1st move of 7 to finish to get the 2nd, 3rd, etc. possible move, I can get all 7 working at the same time to speed up the "thinking" process.

I may just leave it as it is and just worry about the 1 move. But the heuristic is starting to get way too easy to beat since I've learned the pattern of beating it lol. Mainly because it does the same thing every time.

I know there is a way to do it because in a game of chess that I have, I'm sure it has it's own heuristic value that looks ahead several moves (especially on hard). And it only takes about 30 to 45 minutes to make a move on the hardest setting. And I know that that is a LOT of board configurations (13 ^ 64).

Don't fix what ain't broken...just tweak it a little

• 8. srpna 2012 5:19

Serializing objects would be a good idea. But after reading some of the comments, the author said only up to a few thousand would be okay. It would start slowing down the deserializing process, but instead use a database, of which I have already thought about. I'll have to look into that again. I thought about that several years ago when I first started messing with the code, but never got it going. Now that I understand more about what I want, I'll probably get a database going to where I can just use the functions from SQL/MySQL to get faster results on the token values.

Don't fix what ain't broken...just tweak it a little

• 8. srpna 2012 23:27

As for the serializing part, right now yes may be too much for your current method. But perhaps you could think of a way to repackage them into smaller collections.

May the Force be with you young Jedi...

`Console.WriteLine("-Warren");`

If you find someone's post helpful please click the green "up arrow" to the left and vote!
It's Greatly Appreciated =)

• 9. srpna 2012 0:19

One way you could shorten your stored data is to only store the starting location, and the type of pattern to be applied. Such as: 1,1 (starting location) and it was going right (horizontally) so the pattern would be HR (Horizontal Right). Then store a list of patterns, assigning a mathmatic value to the type of pattern. So in order to check for that pattern, we would start at 1,1; then check using a recursive method to see if there are 3 additional pieces connecting to it on the right. So maybe if your storing location like so (x,y), your HR pattern would tell the recursive method to add 1 to the y variable to check for a checker pieces existing next to it, if found continue adding another 1 to the y to see if there is another connection, and so on. Then you wouldn't have to store every single location for each pattern, but only the starting location.

May the Force be with you young Jedi...

`Console.WriteLine("-Warren");`

If you find someone's post helpful please click the green "up arrow" to the left and vote!
It's Greatly Appreciated =)

• 9. srpna 2012 0:24

Also store these in their own object type collection with a property for the starting location, pattern type and maybe a rank to show the higher valued patterns in play. Then you could easily serialize the collection of possible patterns onto disk for future games. There will only be so many starting locations to choose from, and sure each starting location could play in a different direction but it's not like you have to store every game piece location anymore.

May the Force be with you young Jedi...

`Console.WriteLine("-Warren");`

If you find someone's post helpful please click the green "up arrow" to the left and vote!
It's Greatly Appreciated =)

• 16. srpna 2012 2:32

Sorry I hadn't been on lately. Got side tracked. The problem with the recursive method is that in order for "2 in a row" does not necessarily mean next to each other. It could mean checker, space, space, checker or checker, space, checker... There is still 2 in a row.

The loops that are stated in the code find all possible starting positions. For instance, the horizontal checks {0,0}-{0,3} for the first check, {0,1}-{0,4} for the second, {0,2}-{0,5}, {0,3}-{0,6}. {0,4} to {0, 6} is not a starting position because it is included within the first 4 checks. Then it moves down a row and checks the same columns until row 5 is reached. Same for the verticals. It only checks until row = 2..example...{0,0}-{3,0}, {1,0}-{4,0}, {2,0}-{5,0}..{3,0} to {5,0} is not a starting position so it excludes them. The diagonals check the same way. The ending positions of the checks are not in the loops as starting positions.

I'm also not storing every piece into the file. I'm only storing the "playable" positions in the file. In other words, first move has 7 possible plays. {5,0} to {5,6}. The token value of 42 is listed in the file "0.token" as 42|42|42|42|42|42|42. If one of the columns are full, that means there is only 6 available moves. Therefore, the file "boardConfigurationValue.token" would contain 42|42|42|42|42|42. It doesn't store where any pieces are. The board configuration tells it where the pieces are. For instance...no checkers on the board mean a board configuration value of 0. Red checker in the first position would be a board configuration value of 1. White checker in the first position would be a board configuration value of 2 (does not exist because a white checker cannot be on the board without a red checker on the board). Red checker in the second position would be a board configuration value of 3, where a white checker in the second positions would be a board configuration of 6. The pieces placement are not stored in the file...Just the available moves.

Each configuration knows what checkers turn it is by it's value. There is no configuration that has the same number that it can be either red's turn or white's turn. If the configuration is 0, it's red's turn (no checkers on the board..red moves first). If the configuration is 5, it's red's turn (white in position {5,0} (value of 2) + red in position {5,1} (value of 3) ). If the configuration is 9, it's white's turn (red in position {5,2})

I did some research on the Serialize class. I found out that storing data as binary makes the file MUCH larger than storing it as regular text. I tried this out with a simple program that stores the same exact data to each file. This would not be an option. I'm still thinking of putting it in a database which would make searching a LOT faster.

Other than that, I'm not really sure on what I am trying to comprehend with this situation. It's a little over my head I guess and I'm working on a more important application for the time being.

Don't fix what ain't broken...just tweak it a little

• 16. srpna 2012 3:10

its cool, I haven't had a chance yet to read your whole response but I wanted to comment real quick on the recersive method. If you code it right it will only build a pattern for a fully connecting set of 4. You wouldn't have the problem you mentioned about "checker" - "space" - "checker - etc... because as soon as you hit the first space or different color checker piece it would stop trying to build a recursive pattern and basically record that it is not 4 in a row, or that you hit another color which means there could never be a pattern of 4 in a row because it was blocked. If you would like I can write out a quick example. let me know. I have a few things to do and then I'll read through the rest of your response and comment. Cya

May the Force be with you young Jedi...

`Console.WriteLine("-Warren");`

If you find someone's post helpful please click the green "up arrow" to the left and vote!
It's Greatly Appreciated =)

• 16. srpna 2012 3:21

Also, with the "checker, space, checker"...recursive wouldn't work with the heuristic methods as it gives a 2 in a row value with a possible 3 in a row value. My heuristics work great with this and so does the MLearning. I was just trying to figure out the threading part and it seems that we got off that subject somewhere lol. It's ok though because I learned a couple of things down the road.

Sorry I had to unmark the answer, because what was marked as the answer by a moderator had nothing to do with the question that was being asked.

Don't fix what ain't broken...just tweak it a little

• 16. srpna 2012 4:04

So could you explain what you mean by the recursive "gives 2 in a row balue with a possible 3 in a row value"? Perhaps I'm just looking at solving the learning in a different way. The reason I like recursive for pattern checking is that it only goes as far as needed; which of course means less resources being utilized because from my understanding the method your using right now checks every possible location 7 times. recursive would only be utilized to where you could place your next piece.

As for the delegate being updated by each thread there might be a simple fix for that. "locking". This will basically lock the object your attempting to use from each thread and only allow one thread at a time to do something with it. So you might calculate a bunch of things at once with each thread but then the thread will wait for the object to come available to add to it.

```lock (_mboard[,])
{
}
```

May the Force be with you young Jedi...

`Console.WriteLine("-Warren");`

If you find someone's post helpful please click the green "up arrow" to the left and vote!
It's Greatly Appreciated =)

• 16. srpna 2012 4:09

One thing I do need to explain about why the recursive method with heuristics won't work...heuristics calculate, "checker, space, space, space", "space, checker, space, space", "space, space, checker, space", and "space, space, space, checker" as 1 in a row. 2 in a row can have the possibilities of "c, c, s, s", "c, s, c, s", "c, s, s, c", "s, c, c, s", "s, c, s, c", and "s, s, c, c". As long as there are 4 places that can be used by "checker", it's a valid value. If any of the spaces contain an opponent checker, it skips that check. Recursive wouldn't give me those values.

Basically, recursive would only try to find checkers next to each other to give a value which would cause it not "fool" the other player as to what it is trying to do. Having a space between the checkers makes it harder for the opponent to "see" what the player is trying to accomplish. In other words, I may try to build a horizontal at the same time I'm trying to build a diagonal to where I have to make the other player block the horizontal so I can make the diagonal. This is what the heuristics values are building up to. The positive/negative reinforcements for the MLearning are building off of these values as well.

Don't fix what ain't broken...just tweak it a little

• 16. srpna 2012 4:41

I guess I will have to show you an example of how i see it playing out; I don't always explain things very well via text lol. I do understand your goals, but in my head I see a solution using pattern recognition inside the heuristics logic. Don't forget Heuristics is simply a solution based on experience in problem solving. It almost sounds like the methods your utilizing are solving based on an exhaustive search which will tie up a lot more resources. I'm off work the next 4 days so I'll see if I can work on a better example.

Did you see my note on the thread object locking to resolve your shared object issue? I don't think this would slow down your threads enough to notice as long as the thread can complete all it's needed calculations prior to attempting to write to the delegate object. basically each thread would run in sync and when reaching the part to write back to the delegate it would wait until it was available. Also you might want to create an object that handles returning values from each thread and delegate that object to the worker threads; that way if you need the returning values entered in a specific spot on your array it can find out which thread was returning the value to determine where to place it in the _mboard[,] array.

May the Force be with you young Jedi...

`Console.WriteLine("-Warren");`