[iagno/gnome-3-10] Improve computer player behavior
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [iagno/gnome-3-10] Improve computer player behavior
- Date: Mon, 23 Sep 2013 23:36:51 +0000 (UTC)
commit 75eb88a9fa96d3803e8397af92e3a9028d09046b
Author: Dave Paul <hi my name is dave gmail com>
Date: Tue Sep 17 21:21:01 2013 -0600
Improve computer player behavior
This change actually makes use of the around () and eval_heuristic ()
methods to improve the play of the AI player. At level 1, the behavior
is the same as before.
For testing I ran matches against the old computer player which was
playing LIGHT (both sides were at level 2). I ran a full game for each
of the 244 potentially unique openings of 8 pieces (before 8 pieces are
on the board, the computer just plays randomly).
When dark was played by the old code, its record was 100 - 141 - 3.
When dark was played by the new code, its record was 191 - 47- 6.
This is a significant improvement, and may turn out to be too difficult
of an opponent, especially at level 3. We could try reducing the search
depth to compensate... I'm not sure how to judge absolute difficulty of
the AI.
https://bugzilla.gnome.org/show_bug.cgi?id=708179
src/computer-player.vala | 38 ++++++++++++++++++++++----------------
1 files changed, 22 insertions(+), 16 deletions(-)
---
diff --git a/src/computer-player.vala b/src/computer-player.vala
index b3b27c6..04c9813 100644
--- a/src/computer-player.vala
+++ b/src/computer-player.vala
@@ -67,8 +67,10 @@ public class ComputerPlayer
* At the end of the game try and maximise the number of tokens.
* Near the end try and push for a win.
* For the rest of the game try and maximise everything.
+ * Note, for level 1 we default to the "PERFECT" strategy, which is not as
+ * good as the "BEST" strategy, so as not to make the AI too difficult.
*/
- var strategy = Strategy.BEST;
+ var strategy = (level == 1) ? Strategy.PERFECT : Strategy.BEST;
if (tiles_remaining <= depth + 10)
strategy = Strategy.PERFECT;
else if (tiles_remaining <= depth + 12)
@@ -173,6 +175,10 @@ public class ComputerPlayer
return b.n_tiles - a.n_tiles;
}
+ /* Perhaps surprisingly, the *lower* the return value from this method,
+ * the "better" the position. So callers want to minimize the result here
+ * to find the best move.
+ */
private int calculate_heuristic (Game g, Strategy strategy)
{
var tile_difference = g.n_dark_tiles - g.n_light_tiles;
@@ -191,11 +197,11 @@ public class ComputerPlayer
/* Try to maximise a number of values */
default:
- return tile_difference + around () + eval_heuristic ();
+ return tile_difference - around (g) - eval_heuristic (g);
}
}
- private int eval_heuristic ()
+ private static int eval_heuristic (Game g)
{
var count = 0;
for (var x = 0; x < 8; x++)
@@ -203,7 +209,7 @@ public class ComputerPlayer
for (var y = 0; y < 8; y++)
{
var h = heuristic[y * 8 + x];
- if (game.get_owner (x, y) != game.current_color)
+ if (g.get_owner (x, y) != g.current_color)
h = -h;
count += h;
}
@@ -212,7 +218,7 @@ public class ComputerPlayer
return count;
}
- private int around ()
+ private static int around (Game g)
{
var count = 0;
for (var x = 0; x < 8; x++)
@@ -220,20 +226,20 @@ public class ComputerPlayer
for (var y = 0; y < 8; y++)
{
var a = 0;
- a += is_empty (x + 1, y);
- a += is_empty (x + 1, y + 1);
- a += is_empty (x, y + 1);
- a += is_empty (x - 1, y + 1);
- a += is_empty (x - 1, y);
- a += is_empty (x - 1, y - 1);
- a += is_empty (x, y - 1);
- a += is_empty (x + 1, y - 1);
+ a += is_empty (g, x + 1, y);
+ a += is_empty (g, x + 1, y + 1);
+ a += is_empty (g, x, y + 1);
+ a += is_empty (g, x - 1, y + 1);
+ a += is_empty (g, x - 1, y);
+ a += is_empty (g, x - 1, y - 1);
+ a += is_empty (g, x, y - 1);
+ a += is_empty (g, x + 1, y - 1);
/* Two points for completely surrounded tiles */
if (a == 0)
a = 2;
- if (game.get_owner (x, y) != game.current_color)
+ if (g.get_owner (x, y) != g.current_color)
a = -a;
count += a;
}
@@ -242,9 +248,9 @@ public class ComputerPlayer
return count;
}
- private int is_empty (int x, int y)
+ private static int is_empty (Game g, int x, int y)
{
- if (x < 0 || x >= 8 || y < 0 || y >= 8 || game.get_owner (x, y) != Player.NONE)
+ if (x < 0 || x >= 8 || y < 0 || y >= 8 || g.get_owner (x, y) != Player.NONE)
return 0;
return 1;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]