package makise.othello; import othello.*; import java.awt.Point; /** * ごく単純な先読みをするプレーヤー。 * 改変履歴: ver 1.10 評価値の重みを多少まともなものにした * * @version 1.10 */ public class SakiyomiPlayer implements OthelloPlayer { /* 評価値の重み */ private static final int[][] weightTable = { { 15,-5, 3, 3, 3, 3,-5,15 }, { -5,-5, 1, 1, 1, 1,-5,-5 }, { 3, 1, 1, 1, 1, 1, 1, 3 }, { 3, 1, 1, 1, 1, 1, 1, 3 }, { 3, 1, 1, 1, 1, 1, 1, 3 }, { 3, 1, 1, 1, 1, 1, 1, 3 }, { -5,-5, 1, 1, 1, 1,-5,-5 }, { 15,-5, 3, 3, 3, 3,-5,15 }, }; private int myColor; private int thinkLevel = 3; /* 先読みレベル */ public void init(int color, boolean first, String param) { myColor = color; if (param != null) thinkLevel = Integer.parseInt(param); } public Point nextHand(OthelloBoard board) { Position pos = think(board, myColor, thinkLevel); return new Point(pos.x, pos.y); } /* 置くべきコマの位置とそのときの評価値をペアにして返す 置けないときは位置としては null を返す */ private Position think(OthelloBoard origBoard, int color, int level) { int maxX = 0, maxY = 0, maxValue = Integer.MIN_VALUE; /* これを入れるとたまにアプレットに制御が戻るので 精神衛生上よろしい。 */ Thread.yield(); for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { if (origBoard.canPut(x, y, color)) { OthelloBoard board = (OthelloBoard)origBoard.clone(); board.put(x, y, color); int val; if (level <= 0) { val = evalBoard(board, color); } else { Position pos = think(board, -color, level - 1); if (pos == null) val = evalBoard(board, color); else val = -pos.value; } if (val > maxValue) { maxX = x; maxY = y; maxValue = val; } } } } if (maxValue == Integer.MIN_VALUE) return null; else return new Position(maxX, maxY, maxValue); } /* 盤面の評価値を求める color 側にとっての評価値。(color が強い => 値が正) */ private int evalBoard(OthelloBoard board, int color) { int sum = 0; for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { sum += board.get(x, y) * weightTable[y][x]; } } return sum * color; } } /* 置くべき場所と評価値の組 */ class Position { public int x, y; public int value; public Position(int x, int y, int value) { this.x = x; this.y = y; this.value = value; } }