/* **************************************************************************** This file is part of the game 'KJumpingCube' Copyright (C) 1998-2000 by Matthias Kiefer 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **************************************************************************** */ #include "brain.h" #include "cube.h" #include #include #undef DEBUG // uncomment this to get useful messages #include #ifdef DEBUG #include #endif #include "prefs.h" Brain::Brain(int initValue) { setSkill(Prefs::EnumSkill::Beginner); stopped=false; active=false; currentLevel=0; // initialize the random number generator random.setSeed(initValue); } void Brain::setSkill(int newSkill) { _skill=newSkill; switch(_skill) { case Prefs::EnumSkill::Beginner: maxLevel=1; break; case Prefs::EnumSkill::Average: maxLevel=3; break; case Prefs::EnumSkill::Expert: maxLevel=5; break; default: break; } } int Brain::skill() const { return _skill; } void Brain::stop() { stopped=true; } bool Brain::isActive() const { return active; } bool Brain::getHint(int& row, int& column,CubeBox::Player player ,CubeBox box) { if(isActive()) return false; active=true; stopped=false; currentPlayer=player; int i=0,j=0; int moves=0; // how many moves are the favourable ones CubeBox::Player opponent=(player==CubeBox::One)?CubeBox::Two : CubeBox::One; // if more than one cube has the same rating this array is used to select // one coordinate* c2m=new coordinate[box.dim()*box.dim()]; // Array, which holds the assessment of the separate moves double **worth=new double*[box.dim()]; for(i=0;iowner()!=(Cube::Owner)opponent) { if(worth[c2m[i].row][c2m[i].column]>max ) { max=worth[c2m[i].row][c2m[i].column]; } } } #ifdef DEBUG cerr << "found Maximum : " << max << endl; #endif // found maximum more than one time ? int counter=0; for(i=0;iowner() != (Cube::Owner)opponent) { c2m[counter].row=c2m[i].row; c2m[counter].column=c2m[i].column; counter++; } } assert(counter>0); // if some moves are equal, choose a random one if(counter>1) { #ifdef DEBUG cerr << "choosing a random cube: " << endl ; #endif counter=random.getLong(counter); } row=c2m[counter].row; column=c2m[counter].column; #ifdef DEBUG cerr << "cube: " << row << "," << column << endl; #endif } // clean up for(i=0;iprocessEvents(); // if thinking process stopped if(stopped) { currentLevel--; return 0; } // simulate every possible move worth+=doMove(c2m[i].row,c2m[i].column,player,box); } } delete [] c2m; currentLevel--; return worth; } else { // if maximum depth of recursive calls are reached, return the assessment currentLevel--; box.simulateMove(player,row,column); return box.assessField(currentPlayer); } } int Brain::findCubes2Move(coordinate *c2m,CubeBox::Player player,CubeBox& box) { int i,j; int opponent=(player==CubeBox::One)? CubeBox::Two : CubeBox::One; int moves=0; int min=9999; if(_skill==Prefs::EnumSkill::Beginner) { int max=0; for(i=0;iowner() != opponent) { c2m[moves].row=i; c2m[moves].column=j; c2m[moves].val=box[i][j]->value(); if(c2m[moves].val>max) max=c2m[moves].val; moves++; } } // find all moves with maximum value int counter=0; for(i=0;iowner() != opponent) { int val; // check neighbours of every cube val=assessCube(i,j,player,box); #ifdef DEBUG if(currentLevel==0) cerr << i << "," << j << " : " << val << endl; #endif // only if val >= 0 its a favourable move if( val > 0 ) { if(valowner() != opponent) { c2m[moves].row=i; c2m[moves].column=j; c2m[moves].val=( box[i][j]->max() - box[i][j]->value() ); if(c2m[moves].val maxMoves) { // find maxMoves random cubes to move with coordinate* tempC2M=new coordinate[maxMoves]; coordinate tmp={-1,-1,0}; for(i=0;imax()-box[row][column]->value() ); int val; val=diff-temp+1; val=val*(temp+1); return val; } int Brain::getDiff(int row,int column, CubeBox::Player player, CubeBox& box) const { int diff; if(box[row][column]->owner() != (Cube::Owner)player) { diff=( box[row][column]->max() - box[row][column]->value() ); } else { diff=( box[row][column]->max() - box[row][column]->value()+1 ); } return diff; }