reversi-core is a simple reversi library for C.
It's not the fastest library but fast enough for the monte carlo search.
It's not feature rich but sufficient for demo apps of libraries.
- A 64-bit processor
- Meson for building
Most of the functions are here.
reversi-core: RevBoard Struct Reference
Rest of them are here.
reversi-core: include/reversi.h File Reference
meson setup build
meson compile -C build
meson test -C build
meson setup build -Dexamples=false -Dtests=false
meson compile -C build
You don't need to clone the git repo if you build your project with meson.
Save the following text as subprojects/reversi.wrap
.
[wrap-git]
url = https://github.com/matyalatte/reversi-core.git
revision = head
depth=1
[provide]
reversi = reversi_dep
Then, you can use reversi-core in your meson project.
reversi_dep = dependency('reversi', fallback : ['reversi', 'reversi_dep'])
executable('your_exe_name', ['your_code.cpp'], dependencies : [reversi_dep])
meson setup build -Dreversi:examples=false -Dreversi:tests=false
meson compile -C build
int main() {
// Create a new board
RevBoard *board = revNewBoard();
if (board == NULL) {
printf("Failed to create a reversi board.\n");
return 1;
}
// Need this if you use methods that require a random number generator.
revInitGenRandom((unsigned)time(NULL));
// do something to play reversi
// Free a board
revFreeBoard(board);
}
You can get xy coordinates from bitboards.
// Get black disks
int *black_disks = revGetBitboardAsArray(board, DISK_BLACK);
for (int i = 0; i < revCountDisks(board, DISK_BLACK); i++) {
int pos = black_disks[i];
int x = pos % 8;
int y = pos / 8;
printf("disk%d: %d, %d", i, x, y);
}
free(black_disks);
// Get legal moves
int *mobility = revGetMobilityAsArray(board);
for (int i = 0; i < revGetMobilityCount(board); i++) {
int pos = mobility[i];
int x = pos % 8;
int y = pos / 8;
printf("move%d: %d, %d", i, x, y);
}
free(mobility);
You can get a disk from a board.
// Get a disk at (4, 1)
RevDiskType disk_type = revGetDiskXY(board, 4, 1);
if (disk_type == DISK_BLACK) {
// Black
} else if (disk_type == DISK_WHITE) {
// White
} else {
// Empty
}
You can check if a move is legal or not.
if (revIsLegalMoveXY(board, 4, 2)) {
// (4, 2) is a legal move.
} else {
// Illegal!
}
// Set a disk to (2, 3) and get flipped disks
RevBitboard flipped = revMoveXY(board, 2, 3);
int *flipped_array = revBitboardToArray(flipped);
for (int i = 0; i < revCountOnes(flipped); i++) {
int pos = flipped_array[i];
int x = pos % 8;
int y = pos / 8;
printf("flipped%d: %d, %d", i, x, y);
}
free(flipped_array);
You can use revGenMove*()
to generate a move.
// Pick a move randomly.
int move = revGenMoveRandom(board);
printf("move: %d, %d\n", move % 8, move / 8);
revMove(board, move);
// Play 20000 games randomly and use the best move that has the highest win rate.
move = revGenMoveMonteCarlo(board, 20000);
printf("move: %d, %d\n", move % 8, move / 8);
revMove(board, move);
Command-line app to play reversi.
#include <stdio.h>
#include <time.h>
#include "reversi.h"
int inputInt(const char* msg) {
int x = -1;
while ((x < 0) | (x >= 8)) {
printf("%s", msg);
scanf("%d", &x);
fflush(stdin);
}
return x;
}
int main() {
// Initialize
RevBoard *board = revNewBoard();
if (board == NULL) {
printf("Failed to create a reversi board.\n");
return 1;
}
revInitGenRandom((unsigned)time(NULL));
// Iterate until no one can put disks.
while (revHasLegalMoves(board)) {
int move;
if (revGetCurrentPlayer(board) == DISK_BLACK) {
printf("Your turn.\n");
revPrintBoardWithMobility(board);
int x = -1;
int y = -1;
while ((x == -1) | !revIsLegalMoveXY(board, x, y)) {
x = inputInt("x? ");
y = inputInt("y? ");
}
move = revXYToPos(x, y);
} else {
// CPU uses the monte carlo search.
printf("CPU's turn.\n");
revPrintBoardWithMobility(board);
// Finish 20000 games and use the best move that has the highest win rate.
move = revGenMoveMonteCarlo(board, 20000);
}
printf("move: %d, %d\n\n", move % 8, move / 8);
revMove(board, move);
if (!revHasLegalMoves(board)) {
// Pass
revChangePlayer(board);
}
}
RevDiskType winner = revGetWinner(board);
if (winner == DISK_BLACK) {
printf("You win!\n");
} else if (winner == DISK_WHITE) {
printf("You lose.\n");
} else {
printf("Draw.\n");
}
revFreeBoard(board);
return 0;
}
There is a GUI demo for reversi-core.
matyalatte/libui-reversi-demo: Demo app to play reversi using libui-ng and reversi-core