views:

299

answers:

4

I would like to port a chess AI to iPhone, but I can't figure out how to do it. Apparently iPhone doesn't support multi threading so you can't just seperately compile the AI, but have to somehow merge it into the code.

I have a GPL copy of a implementation of the sjeng engine, but I can't figure out how they did it because it's written in c and c++ and all I know is apple objc.

Does anyone have any recommendations on how to do this? I need to make a wrapper of some kind for what is a standalone program.

file with code which I will leave up for as long as I can.

+1  A: 

Objective C is a superset of C, so if the library is written in C, you can just compile it with the rest of your Objective-C code without any wrappers.

Tuomas Pelkonen
But how do I port it from having its own main loop into something like, say, an object?
Nathan McDavitt-Van Fleet
The library needs to have an interface that you can use to get the next AI move.
Tuomas Pelkonen
How does the library receive input? It does not talk straight to the user, does it?
Seva Alekseyev
+1  A: 

iPhone OS does support multithreading; see NSThread class. You won't get any extra performance from it, though - the iPhone CPU is single-core and there's almost no multitasking.

And yes, from the Objective C code you can easily call into C and C++ code, and vice versa. For C++ interaction, rename your sources to .mm; then they're compiled as Objective C++.

I have ample experience porting C++ code to iPhone. Works like a charm.

Seva Alekseyev
I need the AI to be persistant, and I would need to contact it, not just receive callbacks.
Nathan McDavitt-Van Fleet
A: 

Your question is actually more complicated than it needs to be, because I think the basic problem you have is unrelated to compiling specifically for the iPhone.

If you say you already have some chess AI code, then somewhere in there is a call to an evaluation function that takes a game state (board position and player to move) and will give back a move. That's what you need to drill down and find, because that essentially is the "engine" that will drive your app, regardless of what platform you're compiling for.

Now, my guess is that this chess AI assumes that move search is run in its own thread, likely a design decision to make it easy to "interrupt" the search at any time and have it play its own move. You can certainly run code in separate threads on the iPhone, so the problem for you is to figure out how to tease out that code from to free it from whatever existing platform dependencies it has.

It may help you to first approach this problem as if you were writing a command-line utility, in C, to run on Mac OS X. That will free you from a lot of dependencies and simplify the situation for you. My guess is once you've done that, you'll immediately have a good idea of how to make it work within a (Cocoa) iPhone environment.

Shaggy Frog
+1  A: 

I have successfully ported a chess engine to iPhone. It's not difficult for the porting. Most of the popular chess engines adopt Universal Chess Interface Protocol or Chess Engine Communication Protocol. Read Wikipedia for more details on each protocol.

Now, say you take one of the open sources UCI chess engine and it compiles on C or C++. XCode supports C and C++ natively, so all you will need to do is copy the sources to XCode and they will compile.

The next phase would be connecting the engine to your interface. Again, this is not difficult. You will need to send protocol commands to the engine, the engine would give you back the results on standard output. You would need to pipe results using UNIX's pipe(). Read my other thread http://stackoverflow.com/questions/3619252/fork-on-iphone for more details.

Example:

Assume engine_loop is the game loop for your engine (all engines must have a loop).

engine_loop(int fd[])
{
  dup2(fd[1], STANDARD_OUTPUT);

  while(true)
  {
    printf("e4\n"); // This is dumb, we always make the same move, but you get the idea
  }
}

my_objective_c_function()
{
  int fd[2];
  pipe(fd);
  engine_loop(fd);
  char buffer[1024];
  read(fd[0], buffer, 1024);

  // buffer == "e4"

  // Send "e4" to the interface
}

The code fragment shows you how to send results from an engine to your interface. Now, you will need to do the other way around. This is very similar to the code above. In a real scenario, once your connection is established, you will need to send UCI commands, I will give you an example:

ucinew
isready
go infinite
stop

Please read the UCI chess engine protocol documentation carefully. You will need it.

Kinderchocolate