/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (c) 2007 Antoine Cellerier * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "reversi-strategy.h" /** * Simple strategy: * A very simple strategy. Makes the highest scoring move taking the other * player's next best move into account. * From Algorithm by Claudio Clemens in hinversi, simpleClient.c */ static void reversi_copy_board(reversi_board_t *dst, const reversi_board_t *src) { int i; rb->memcpy(dst->history,src->history, (BOARD_SIZE*BOARD_SIZE - INIT_STONES)*sizeof(move_t)); for(i=0;imemcpy(dst->board[i],src->board[i],BOARD_SIZE*sizeof(int)); } } static int reversi_sim_move(const reversi_board_t *game, const int row, const int col, const int player) { reversi_board_t game_clone; reversi_copy_board(&game_clone,game); return reversi_make_move(&game_clone,row,col,player); } static int reversi_get_max_moves(const reversi_board_t *game, int player) { int max = -BOARD_SIZE*BOARD_SIZE; int row, col; for(row=0; rowmax) max = v; } } return max; } static int reversi_sim_move2(const reversi_board_t *game, const int row, const int col, const int player) { /* Takes the other player's next best move into account */ int score; reversi_board_t game_clone; reversi_copy_board(&game_clone,game); score = reversi_make_move(&game_clone,row,col,player); return score - reversi_get_max_moves(&game_clone, reversi_flipped_color(player)); } static move_t simple_move_func(const reversi_board_t *game, int player) { int max = -BOARD_SIZE*BOARD_SIZE; int count = 0; int row, col; int r; for(row=0; rowmax) { max = v; count = 1; } else if(v==max) { count ++; } } } if(!count) return MOVE_INVALID; /* chose one of the moves which scores highest */ r = rb->rand()%count; row = 0; col = 0; while(true) { if(reversi_sim_move2(game, row, col, player)==max) { r--; if(r<0) { return MAKE_MOVE(row,col,player); } } col ++; if(col==BOARD_SIZE) { col = 0; row ++; if(row==BOARD_SIZE) { row = 0; } } } } const game_strategy_t strategy_simple = { true, NULL, simple_move_func };