/*****************************************************************************\ * FILE: SimpleHeuristic.cpp * * PURPOSE: Implementation of the SimpleHeuristic class * * Created by Eric Akers, 30 Dec 2003 * * ChangeLog: * ELA - - Initial Working Version * * * * * Copyright (C) 2003 Eric Akers * * 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 \*****************************************************************************/ // Header Files ############################################################# #include #include "SimpleHeuristic.h" // Macros ################################################################### // Structures ############################################################### // Class Function Definitions ############################################### SimpleHeuristic::SimpleHeuristic() : Board() {} long int SimpleHeuristic::getHeuristicValue( int player ) const { long int heuristic = 0; for( int row=0; row<19; row++ ) { for( int col=0; col<19; col++ ) { if( board[col][row] == Board::BLANK ) { // Nothing to see here continue; } // printf( "*** (%d,%d) Player: %d ***\n", row, col, board[col][row] ); for( int i=0; i<8; i+=2 ) { // Get the length in this direction. Do not add to the total // heuristic if there is the same existing piece in the // opposite direction. int fullCountForward, fullCountBackward; int numOpenForward, numOpenBackward; int lengthForward, lengthBackward; bool fullOpen = true; getNumAdjacentPieces( row, col, i, lengthForward, numOpenForward, fullCountForward ); getNumAdjacentPieces( row, col, i+1, lengthBackward, numOpenBackward, fullCountBackward ); // If there is a piece to the back, then do not bother because // this conect has already been handled if( lengthBackward > 0 ) { // printf( "direction: %d, length backward: %d\n", i, lengthBackward ); continue; } // Determine if there is the ability to complete five in a row int totalLength = lengthForward + 1; // printf( "\nTotal length: %d\n", totalLength ); // printf( "Open Forward: %d, open backward: %d. ", numOpenForward, numOpenBackward ); if( totalLength > 5 ) { // printf( "TOTAL LENGTH > 5\n" ); totalLength = 5; } if( numOpenForward + numOpenBackward >= 4 ) { // Determine if both are closed if( lengthForward == numOpenForward && lengthBackward == numOpenBackward ) { // printf( "Is CLOSED\n" ); // Don't add to the heuristic since this does nothing continue; } // Determine if one side is open else if( lengthForward == numOpenForward || lengthBackward == numOpenBackward ) { // Partially open // printf( "PARTIALLY OPEN\n" ); fullOpen = false; } else { // printf( "is OPEN\n" ); } // Add to the heuristic value the full length. int totalOpen = fullCountForward + 1; if( totalOpen >= 5 ) { // Make it four. totalOpen = 4; } // printf( "Get heuristic for length: %d\n", totalOpen ); if( board[col][row] == player ) { heuristic += getHeuristicForLength( totalOpen, fullOpen ); // If the open length is greater than the actual length, subtract // some value as this is not as good as others if( totalOpen == 4 && totalOpen != totalLength ) { // printf( "Not full length, -10\n" ); heuristic -= 10; } } else { heuristic -= getHeuristicForLength( totalOpen, fullOpen ); // If the open length is greater than the actual length, subtract // some value as this is not as good as others if( totalOpen == 4 && totalOpen != totalLength ) { // printf( "Not full length, -10\n" ); heuristic += 10; } } // printf( "New heuristic: %ld\n", heuristic ); } } // For i } // For col } // For row return heuristic; } int SimpleHeuristic::getHeuristicForLength( int length, bool bothEndsOpen ) const { int val; switch( length ) { case 1: if( bothEndsOpen ) { val = LENGTH_ONE_OPEN; } else { val = LENGTH_ONE_CLOSED; } break; case 2: if( bothEndsOpen ) { val = LENGTH_TWO_OPEN; } else { val = LENGTH_TWO_CLOSED; } break; case 3: if( bothEndsOpen ) { val = LENGTH_THREE_OPEN; } else { val = LENGTH_THREE_CLOSED; } break; case 4: if( bothEndsOpen ) { val = LENGTH_FOUR_OPEN; } else { val = LENGTH_FOUR_CLOSED; } break; case 5: val = LENGTH_FIVE; break; default: printf( "INVALID LENGTH OF CHAIN!\n" ); exit( -1 ); } return val; }