/*************************************************************************** * Copyright (C) 2009 by Stefan Bühler * * stbuehler@web.de * * * * 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 program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "ai.h" namespace toruschess { // NOPIECE = 0, PAWN = 1, KNIGHT = 2, BISHOP = 3, ROOK = 4, QUEEN = 5, KING = 6 static int piece_value[] = { 0, 1, 3, 3, 5, 9, 10 }; static const int MAXVAL = 10000; static const int NOMOVE = -MAXVAL - 1; static const int DRAWVAL = -7; /* standard minimax search; saves the best move in *move if move != NULL; * balance is the current "heuristic value" of a state (mult with curp to get the * rating for a specifig player) */ static int minimax(Field &field, int bal, Player curp, unsigned int depth, Move *move) { if (depth == 0) return curp * bal; int mx = NOMOVE; for (int x = 0; x < 8; x++) for (int y = 0; y < 8; y++) { Pos p(x, y); if (field.player(p) != curp) continue; int cbal = bal; QList moves = field.validMoves(p); foreach(Move m, moves) { field.move_unchecked(m); cbal -= m.prevTo(); int val = -minimax(field, cbal, Player(-curp), depth-1, NULL); if (val > mx) { mx = val; if (move) *move = m; } field.undo_unchecked(m); if (mx == MAXVAL) return mx; } } if (mx == NOMOVE) { if (field.inCheck(curp)) return -MAXVAL; return curp * DRAWVAL; } return mx; } Move ai::getMove(Field &field, Player curp, int depth) { int balance = 0; for (int x = 0; x < 8; x++) for (int y = 0; y < 8; y++) { Pos p(x,y); balance += field.player(p) * piece_value[field.piece(p)]; } Move move; minimax(field, balance, curp, depth, &move); return move; } }