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
25AI_Newton::AI_Newton()
26{
27}
28
29int 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