I'd like to introduce myself to the Rust Community and to present RUSThello, a little project I've been working on.
As I wanted to give Rust a try, I began working on a simple implementation of Reversi (a popular boardgame also known as Othello). It is now up and running, featuring a simple shell interface and a not too bad AI, so I thought of sharing it with you:
As a disclaimer, I have to warn you all that I am not a professional computer programmer or a Computer Science student, so please keep your expectations low: my main goal was not to produce awesome software, but just to learn a new programming language and have some fun. At best, RUSThello may be reguarded as a simple example of Rust program for beginners like me; at worst, as a collection of mistakes for Rust programmers to avoid.
Of course, any comment or suggestion on the program itself or on my use of Rust would be most appreciated (and let me know if you can defeat the AI)!
Nice stuff! I have skimmed through your code and there were not really anything that stood out to me, except for how you iterate over the board. This is an alternative way of iterating over the board and avoid bounds checks for each access:
// For every row add a row reference to the left
for (row_n, row) in board.iter().enumerate() {
board_to_string = board_to_string + "\t" + &((row_n + 1).to_string()) + " ";
// For every column, add the appropriate character depending on the content of the current cell
for (col_n, cell) in row.iter().enumerate() {
match cell {
This example is for src/interface/mod.rs, but I have seen it in more places. I would recommend looking more into iterators in general. They are incredibly useful.
I haven't managed to beat the AI yet, but I'm not that good at this game anyway. I did, however, write a free standing Othello AI for a university assignment and it would be cool if there was a way to connect an external AI to this game in a similar way. You could let the user enter a path to the AI binary and use a simple interface, like the one we used:
$ path/to/my_ai X XOOX...XX.O(and so on)
5 2
The first argument is the AI player's character and the second argument is a flat representation of the board. The AI program would analyse the game and print the coordinates for its next move. It would be fun to pitch AIs against each other. Maybe I should port my AI to Rust and see how it performs against the C original...
Your suggerstion regarding the iterators looks extra interesting and may significantly improve performances. I tried to take extra care, while writing the code, to make computations efficient, but I have no idea whatsoever on how to produce faster code. I'm sure a good programmer could write dramatically faster code than this!
To have an interface to connect external AIs is a wonderful idea as well, I'd like to implement it. I'm afraid that this will require some time, but I should be able to make it eventually. At the moment I'm testing my AI against other ones by manually transferring moves from one program to the other, but of course this is not the optimal way.
Using more iterators would probably speed things up, because the indexing would then always be known to be correct and no bounds checking would be performed. You can use them to do all sorts of stuff, like computing the score or, as I showed, print the board.
It would be like implementing a new opponent, but this opponent would call an other program. I don't know how easy/hard it would be to make it work with any AI, but I guess it would be possible to make wrapper scripts if they are quite similar.
I am in the process of releasing a major refactoring. I took @ogeon's suggestion about external AIs seriously and this led me to the following changes. Now there is a rusthello_lib library implementing the basic Reversi mechanics and a main rusthello binary which contains the proper game.
AIs can be any program taking the board encoded as a string in input, and returning the coordinates of the chosen move as output. Then you just need to insert the path of the executable at the beginning of the game, and the rest will work by itself. I already converted some of my AIs to work like that.
BEWARE: This is a first implementation which I won't have time do properly finish nor document for a couple of weeks at least. Feel free to give it a look though, I am always happy to have feedback.
With the lastest commit I have furthered the modularisation effort, and I am quite happy with the result. Most notably, the file structure has been simplified, rusthello_lib polished, and some small change to the interface made. rusthello_lib has some documentation improvements as well (the documentation can be produced by cargo doc).
It would be super cool if someone wrote and tried an external AI (not necessarily in Rust) to see if everything works fine, and to challenge my AIs as well! If someone is interested, I would happily help with clarifications on how the interface for the external AIs works (although I promise it's super-simple).