File indexing completed on 2024-05-19 04:04:53
0001 /* 0002 This file is part of the game 'KJumpingCube' 0003 0004 SPDX-FileCopyrightText: 1998-2000 Matthias Kiefer <matthias.kiefer@gmx.de> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "ai_newton.h" 0010 0011 AI_Newton::AI_Newton() 0012 { 0013 } 0014 0015 int AI_Newton::assessCube (const int index, const Player player, 0016 const int neighbors [4], const Player owners[], 0017 const int values[], const int maxValues[] 0018 ) const 0019 { 0020 enum Value {StrongerOpponent = HighValue, 0021 TakeOrBeTaken = 1, EqualOpponent, CanTake, 0022 OccupyCorner, OccupyEdge, OccupyCenter, 0023 CanConsolidate, 0024 CanReachMaximum, CanExpand, IncreaseEdge, IncreaseCenter, 0025 PlayHereAnyway}; 0026 Player p = player; // This player. 0027 Player o = (p == One) ? Two : One; // The other player. 0028 Player cOwner = owners[index]; // This cubes's owner. 0029 0030 int pCount = 0; 0031 int pRank = 4; 0032 int oCount = 0; 0033 int oRank = 4; 0034 int cRank = maxValues[index] - values[index]; 0035 int pos = 0; 0036 0037 // Get statistics for neighbors: count and best rank for player and other. 0038 for (int i = 0; i < 4; i++) { 0039 if ((pos = neighbors [i]) < 0) { 0040 continue; // No neighbor on this side. 0041 } 0042 int rank = maxValues[pos] - values[pos]; 0043 if (owners[pos] == p) { // Neighbor is owned by this player. 0044 pCount++; 0045 pRank = (rank < pRank) ? rank : pRank; 0046 } 0047 else if (owners[pos] == o) { // Neighbor is owned by other player. 0048 oCount++; 0049 oRank = (rank < oRank) ? rank : oRank; 0050 } 0051 else { // Otherwise, nobody owns it. 0052 oRank = (rank < oRank) ? rank : oRank; 0053 } 0054 } 0055 0056 if (oRank < cRank) return StrongerOpponent; 0057 // return PlayHereAnyway; // IDW test. Try ALL REASONABLE MOVES. 0058 0059 if ((cRank <= 0) && (oRank <= 0)) return TakeOrBeTaken; // Value 1. 0060 if ((cRank == oRank) && (oCount > 0)) return EqualOpponent; // Value 2. 0061 if ((cRank <= 0) && (oCount > 0)) return CanTake; // Value 3. 0062 0063 bool vacant = (cOwner == Nobody); 0064 bool nVacant = ((pCount + oCount) == 0); 0065 int cMax = maxValues[index]; 0066 if (vacant && nVacant && (cMax == 2)) return OccupyCorner; // Value 4. 0067 if (vacant && nVacant && (cMax == 3)) return OccupyEdge; // Value 5. 0068 if (vacant && nVacant && (cMax == 4)) return OccupyCenter; // Value 6. 0069 // Sun 2 Dec 2012 - This seems to play well on sizes 3, 5 and 7. 0070 return PlayHereAnyway; // IDW test. Ignore val > 6. Try ALL REASONABLE MOVES. 0071 }