1 | /* **************************************************************************** |
2 | This file is part of the game 'KJumpingCube' |
3 | |
4 | Copyright (C) 1998-2000 by Matthias Kiefer |
5 | <matthias.kiefer@gmx.de> |
6 | |
7 | This program is free software; you can redistribute it and/or modify |
8 | it under the terms of the GNU General Public License as published by |
9 | the Free Software Foundation; either version 2 of the License, or |
10 | (at your option) any later version. |
11 | |
12 | This program is distributed in the hope that it will be useful, |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | GNU General Public License for more details. |
16 | |
17 | You should have received a copy of the GNU General Public License |
18 | along with this program; if not, write to the Free Software |
19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
20 | |
21 | **************************************************************************** */ |
22 | |
23 | #include "ai_newton.h" |
24 | |
25 | AI_Newton::AI_Newton() |
26 | { |
27 | } |
28 | |
29 | int AI_Newton::assessCube (const int index, const Player player, |
30 | const int neighbors [4], const Player owners[], |
31 | const int values[], const int maxValues[] |
32 | ) const |
33 | { |
34 | enum Value {StrongerOpponent = HighValue, |
35 | TakeOrBeTaken = 1, EqualOpponent, CanTake, |
36 | OccupyCorner, OccupyEdge, OccupyCenter, |
37 | CanConsolidate, |
38 | CanReachMaximum, CanExpand, IncreaseEdge, IncreaseCenter, |
39 | PlayHereAnyway}; |
40 | Player p = player; // This player. |
41 | Player o = (p == One) ? Two : One; // The other player. |
42 | Player cOwner = owners[index]; // This cubes's owner. |
43 | |
44 | int pCount = 0; |
45 | int pRank = 4; |
46 | int oCount = 0; |
47 | int oRank = 4; |
48 | int cRank = maxValues[index] - values[index]; |
49 | int nCount = 0; |
50 | int pos = 0; |
51 | |
52 | // Get statistics for neighbors: count and best rank for player and other. |
53 | for (int i = 0; i < 4; i++) { |
54 | if ((pos = neighbors [i]) < 0) { |
55 | continue; // No neighbor on this side. |
56 | } |
57 | int rank = maxValues[pos] - values[pos]; |
58 | if (owners[pos] == p) { // Neighbor is owned by this player. |
59 | pCount++; |
60 | pRank = (rank < pRank) ? rank : pRank; |
61 | } |
62 | else if (owners[pos] == o) { // Neighbor is owned by other player. |
63 | oCount++; |
64 | oRank = (rank < oRank) ? rank : oRank; |
65 | } |
66 | else { // Otherwise, nobody owns it. |
67 | oRank = (rank < oRank) ? rank : oRank; |
68 | } |
69 | } |
70 | |
71 | if (oRank < cRank) return StrongerOpponent; |
72 | // return PlayHereAnyway; // IDW test. Try ALL REASONABLE MOVES. |
73 | |
74 | if ((cRank <= 0) && (oRank <= 0)) return TakeOrBeTaken; // Value 1. |
75 | if ((cRank == oRank) && (oCount > 0)) return EqualOpponent; // Value 2. |
76 | if ((cRank <= 0) && (oCount > 0)) return CanTake; // Value 3. |
77 | |
78 | bool vacant = (cOwner == Nobody); |
79 | bool nVacant = ((pCount + oCount) == 0); |
80 | int cMax = maxValues[index]; |
81 | if (vacant && nVacant && (cMax == 2)) return OccupyCorner; // Value 4. |
82 | if (vacant && nVacant && (cMax == 3)) return OccupyEdge; // Value 5. |
83 | if (vacant && nVacant && (cMax == 4)) return OccupyCenter; // Value 6. |
84 | // Sun 2 Dec 2012 - This seems to play well on sizes 3, 5 and 7. |
85 | return PlayHereAnyway; // IDW test. Ignore val > 6. Try ALL REASONABLE MOVES. |
86 | if ((cRank <= 0) && (pCount == 0)) return CanExpand; // Value 9. |
87 | if ((cRank <= 0) && (pCount > 0)) return CanConsolidate; // Value 7. |
88 | if (cRank == 1) return CanReachMaximum;// Value 8. |
89 | if (cMax == 3) return IncreaseEdge; // Value 10. |
90 | if (cMax == 4) return IncreaseCenter; // Value 11. |
91 | |
92 | return PlayHereAnyway; // Value 12. |
93 | } |
94 | |