[iagno] Introduce mainlines.
- From: Arnaud B. <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [iagno] Introduce mainlines.
- Date: Sat, 17 Aug 2019 09:36:54 +0000 (UTC)
commit 28c533a86f861f87733bc7212960894b28ac4ae8
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Wed Aug 14 23:33:12 2019 +0200
Introduce mainlines.
Since last patch the
hard AI is sometimes
making hard mistakes
by easily offering a
corner. Fix that, by
introducing a simple
"penalty" mechanism.
src/computer-reversi.vala | 75 +++++++++++++++++++++++++++++++++++++++++++++--
src/game.vala | 30 +++++++++++++++++++
src/iagno.vala | 2 +-
3 files changed, 103 insertions(+), 4 deletions(-)
---
diff --git a/src/computer-reversi.vala b/src/computer-reversi.vala
index 5021a1b..cce25d4 100644
--- a/src/computer-reversi.vala
+++ b/src/computer-reversi.vala
@@ -124,7 +124,7 @@ private class ComputerReversiHard : ComputerReversi
calculate_dir_heuristic (ref comparator, move.x, move.y, -1, 1, move.n_tiles_so);
calculate_dir_heuristic (ref comparator, move.x, move.y, -1, 0, move.n_tiles_o );
calculate_dir_heuristic (ref comparator, move.x, move.y, -1, -1, move.n_tiles_no);
- if (medium_ai) /* we artificially decrease the medium difficulty level 1/3 */
+ if (medium_ai) /* we artificially decrease the medium difficulty level 1/4 */
return comparator + (int) heuristic [move.x, move.y] - 8 * (int) neighbor_tiles [move.x, move.y];
else
return 2 * comparator + (int) heuristic [move.x, move.y] - 8 * (int) neighbor_tiles [move.x,
move.y];
@@ -163,7 +163,7 @@ private class ComputerReversiHard : ComputerReversi
{
if (even_depth)
count -= tile_heuristic / 2;
- else if (!medium_ai) /* we artificially decrease the medium difficulty level 2/3 */
+ else if (!medium_ai) /* we artificially decrease the medium difficulty level 2/4 */
count += tile_heuristic / 2;
}
else if (g.is_current_color (x, y))
@@ -172,9 +172,78 @@ private class ComputerReversiHard : ComputerReversi
count -= tile_heuristic;
}
+ if (medium_ai)
+ return count; /* we artificially decrease the medium difficulty level 3/4 */
+
+ mainline_penalty (g, border_penalty, ref count, MainLine.TOP);
+ mainline_penalty (g, border_penalty, ref count, MainLine.LEFT);
+ mainline_penalty (g, border_penalty, ref count, MainLine.RIGHT);
+ mainline_penalty (g, border_penalty, ref count, MainLine.BOTTOM);
+ mainline_penalty (g, corner_penalty, ref count, MainLine.TOPLEFT);
+ mainline_penalty (g, corner_penalty, ref count, MainLine.TOPRIGHT);
+
return count;
}
+ private const int16 border_penalty = 22;
+ private const int16 corner_penalty = 23;
+ private static void mainline_penalty (GameStateStruct g, int16 penalty, ref int16 count, MainLine
mainline_id)
+ {
+ Player [] mainline = g.get_mainline (mainline_id);
+ if (mainline [1] == g.current_color
+ && mainline [0] == Player.NONE)
+ {
+ uint8 i = 1;
+ do { i++; if (i == g.size - 2) break; }
+ while (mainline [i] == g.current_color);
+ if (i != g.size - 2)
+ {
+ count -= penalty;
+ if (mainline [i + 1] == g.current_color)
+ count -= penalty;
+ }
+ }
+ else if (mainline [1] == g.opponent_color
+ && mainline [0] == Player.NONE)
+ {
+ uint8 i = 1;
+ do { i++; if (i == g.size - 2) break; }
+ while (mainline [i] == g.opponent_color);
+ if (i != g.size - 2)
+ {
+ count += penalty;
+ if (mainline [i + 1] == g.opponent_color)
+ count += penalty;
+ }
+ }
+ if (mainline [g.size - 2] == g.current_color
+ && mainline [g.size - 1] == Player.NONE)
+ {
+ uint8 i = 1;
+ do { i++; if (i == g.size - 2) break; }
+ while (mainline [g.size - 1 - i] == g.current_color);
+ if (i != g.size - 2)
+ {
+ count -= penalty;
+ if (mainline [g.size - 2 - i] == g.current_color)
+ count -= penalty;
+ }
+ }
+ else if (mainline [g.size - 2] == g.opponent_color
+ && mainline [g.size - 1] == Player.NONE)
+ {
+ uint8 i = 1;
+ do { i++; if (i == g.size - 2) break; }
+ while (mainline [g.size - 1 - i] == g.opponent_color);
+ if (i != g.size - 2)
+ {
+ count += penalty;
+ if (mainline [g.size - 2 - i] == g.opponent_color)
+ count += penalty;
+ }
+ }
+ }
+
/*\
* * heuristic table
\*/
@@ -201,7 +270,7 @@ private class ComputerReversiHard : ComputerReversi
else
create_heuristic (size, out heuristic);
- if (medium_ai) /* we artificially decrease the medium difficulty level 3/3 */
+ if (medium_ai) /* we artificially decrease the medium difficulty level 4/4 */
return;
/* that part is fun */
diff --git a/src/game.vala b/src/game.vala
index 11d8b21..deaffbc 100644
--- a/src/game.vala
+++ b/src/game.vala
@@ -20,6 +20,16 @@
along with GNOME Reversi. If not, see <https://www.gnu.org/licenses/>.
*/
+private enum MainLine
+{
+ TOP,
+ LEFT,
+ RIGHT,
+ BOTTOM,
+ TOPLEFT,
+ TOPRIGHT;
+}
+
private struct GameStateStruct
{
public Player current_color;
@@ -427,6 +437,26 @@ private struct GameStateStruct
if (ypp_is_valid) empty_neighbors [xpp, ypp] -= 1;
}
}
+
+ /*\
+ * * mainlines
+ \*/
+
+ internal Player [] get_mainline (MainLine mainline_id) // keeping an updated copy of each mainline is a
bit slower
+ {
+ Player [] mainline = new Player [size];
+ switch (mainline_id)
+ {
+ case MainLine.TOP: for (uint8 i = 0; i < size; i++) mainline [i] = tiles [i, 0];
break;
+ case MainLine.LEFT: for (uint8 i = 0; i < size; i++) mainline [i] = tiles [0, i];
break;
+ case MainLine.RIGHT: for (uint8 i = 0; i < size; i++) mainline [i] = tiles [size - 1, i];
break;
+ case MainLine.BOTTOM: for (uint8 i = 0; i < size; i++) mainline [i] = tiles [i, size - 1];
break;
+ case MainLine.TOPLEFT: for (uint8 i = 0; i < size; i++) mainline [i] = tiles [i, i];
break;
+ case MainLine.TOPRIGHT: for (uint8 i = 0; i < size; i++) mainline [i] = tiles [size - 1 - i, i];
break;
+ default: assert_not_reached ();
+ }
+ return mainline;
+ }
}
private class GameStateObject : Object
diff --git a/src/iagno.vala b/src/iagno.vala
index 6502301..120e59f 100644
--- a/src/iagno.vala
+++ b/src/iagno.vala
@@ -449,7 +449,7 @@ private class Iagno : Gtk.Application, BaseApplication
{
case 1 : computer = new ComputerReversiEasy (game); break;
case 2 : computer = new ComputerReversiHard (game, /* depth */ 1); break;
- case 3 : computer = new ComputerReversiHard (game, /* depth */ 2); break; /* FIXME AI makes
mistakes like #LLL#LL# on a border */
+ case 3 : computer = new ComputerReversiHard (game, /* depth */ 2); break;
default: assert_not_reached ();
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]