forked from: Reversi
AIを強化しました。(中級者向け)
CPUから手を変えるような工夫をいれました。
/**
* Copyright hamlet ( http://wonderfl.net/user/hamlet )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/4GIx
*/
/**
* Copyright hamlet ( http://wonderfl.net/user/hamlet )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/4GIx
*/
// forked from ProjectNya's Reversi
////////////////////////////////////////////////////////////////////////////////
// リバーシ Plus for AS3.0
// ※ProjectNya's ReversiのAI強化版
//
// special thanks to ProjectNya
// リバーシ for AS3.0 (1)
// http://www.project-nya.jp/modules/weblog/details.php?blog_id=1039
//
// special thanks to QURAGE
// http://qurage.net/labo/fl1/data/reversi.html
////////////////////////////////////////////////////////////////////////////////
package {
import flash.display.Sprite;
import flash.display.Shape;
import flash.geom.Matrix;
import flash.display.GradientType;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.filters.DropShadowFilter;
[SWF(backgroundColor="#FFFFFF", width="465", height="465", frameRate="30")]
public class Main extends Sprite {
private static var color1:uint = 0x3F68AB;
private static var color2:uint = 0x77B2EE;
private static var tColor:uint = 0xFFFFFF;
private static var sColor:uint = 0x00000;
private static var fontType:String = "_ゴシック";
public function Main() {
//Wonderfl.capture_delay(10);
init();
}
private function init():void {
draw(465, 465);
var game:Game = new Game();
addChild(game);
game.x = 42;
game.y = 12;
}
private function draw(w:uint, h:uint):void {
var colors:Array = [color1, color2];
var alphas:Array = [1, 1];
var ratios:Array = [0, 255];
var matrix:Matrix = new Matrix();
matrix.createGradientBox(w, h, 1.25*Math.PI, 0, 0);
graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix);
graphics.drawRect(0, 0, w, h);
graphics.endFill();
var tf:TextFormat = new TextFormat();
tf.font = fontType;
tf.size = 32;
tf.align = TextFormatAlign.LEFT;
var title:TextField = new TextField();
addChild(title);
title.x = 20;
title.y = 2;
title.width = 200;
title.height = 40;
title.type = TextFieldType.DYNAMIC;
title.selectable = false;
//title.embedFonts = true;
//title.antiAliasType = AntiAliasType.ADVANCED;
title.defaultTextFormat = tf;
title.textColor = tColor;
//タイトル修正 (by Hamlet)
title.text = "Reversi +";
var shade:DropShadowFilter = new DropShadowFilter(1, 90, sColor, 0.4, 4, 4, 2, 2, false, false);
title.filters = [shade];
}
}
}
//////////////////////////////////////////////////
// リバーシ全体を管理するクラス
//////////////////////////////////////////////////
import adobe.utils.CustomActions;
import flash.display.Sprite;
class Game extends Sprite {
private static var pieces:uint = 8;
private var board:Board;
private var score:Score;
private var help:Help;
public static const INIT:String = "init";
public static const PLAY:String = "play";
public static const PUT:String = "put";
public static const FINISH:String = "finish";
public static const NO_POINT:String = "noPoint";
public static const READY:String = "ready";
public static const RESET:String = "reset";
public static const NO_HELP:String = "";
public static const MOVE:String = "move";
public static const SELECT:String = "select";
public static const PUT_COMPLETE:String = "putComplete";
public static const TURN_COMPLETE:String = "turnComplete";
public function Game() {
init();
}
private function init():void {
board = new Board();
score = new Score();
help = new Help();
addChild(board);
board.x = 22;
board.y = 88;
addChild(score);
addChild(help);
help.x = 194;
help.y = 245;
board.init(score, help);
}
}
//////////////////////////////////////////////////
// 盤面を管理するクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.net.navigateToURL;
import flash.net.URLRequest;
import flash.events.MouseEvent;
import flash.utils.escapeMultiByte;
class Board extends Sprite {
private var mode:String;
private var player:uint = 0;
private var map:Map;
private var score:Score;
private var help:Help;
private var manager:Manager;
private var cursor:Cursor;
private static var pieces:uint = 8;
private static var bColor:uint = 0x336600;
private var pointList:Array;
private var pieceList:Array;
private static var pid:uint = 0;
private var completed:uint = 0;
private static var initTime:uint = 500;
private static var startTime:uint = 1000;
private static var cpuTime:uint = 500;
private static var finishTime:uint = 1000;
private static var resetTime:uint = 500;
private var cpu:Object;
private var turns:uint;
private var passed1:Boolean = false;
private var passed2:Boolean = false;
//サウンド
private var seready:SoundEffect;
private var seput:SoundEffect;
private var seturn:SoundEffect;
private var sefanfare:SoundEffect;
private var seclaps:SoundEffect;
private var sefailure:SoundEffect;
private var source1:String = "http://www.project-nya.jp/images/flash/reversi/ready.mp3";
private var source2:String = "http://www.project-nya.jp/images/flash/reversi/put.mp3";
private var source3:String = "http://www.project-nya.jp/images/flash/reversi/turn.mp3";
private var source4:String = "http://www.project-nya.jp/images/flash/reversi/fanfare.mp3";
private var source5:String = "http://www.project-nya.jp/images/flash/reversi/claps.mp3";
private var source6:String = "http://www.project-nya.jp/images/flash/reversi/failure.mp3";
//twitter
private var twitterBtn:Btn;
private static var twitterPath:String = "http://twitter.com/home/?status=";
private var msgs:Array = new Array();
private var result:String;
private static var tag:String = " http://wonderfl.net/c/vDfO"
public function Board() {
draw();
seready = new SoundEffect();
seput = new SoundEffect();
seturn = new SoundEffect();
sefanfare = new SoundEffect();
seclaps = new SoundEffect();
sefailure = new SoundEffect();
}
public function init(s:Score, h:Help):void {
score = s;
help = h;
seready.load(source1, "ready");
seput.load(source2, "put");
seturn.load(source3, "turn");
sefanfare.load(source4, "fanfare");
seclaps.load(source5, "claps");
sefailure.load(source6, "failure");
reset(null);
}
//カーソル位置にコマを配置する(キー設定)
private function initialize():void {
manager = new Manager(this);
addChild(manager);
manager.addEventListener(Game.READY, readySelect, false, 0, true);
manager.addEventListener(Game.MOVE, moveCursor, false, 0, true);
manager.addEventListener(Game.SELECT, selectCursor, false, 0, true);
manager.addEventListener(Game.RESET, resetSelect, false, 0, true);
manager.enable = false;
cpu = new Object();
}
private function reset(evt:TimerEvent):void {
if (evt) evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, reset);
initialize();
map = new Map();
score.init();
mode = Game.INIT;
score.showMessage(mode);
help.show("ready?");
score.resetTime();
seready.play("ready", 1);
manager.help = Game.READY;
if (pieceList) clearPieces();
pieceList = new Array();
}
private function readySelect(evt:Event):void {
manager.help = Game.NO_HELP;
var timer:Timer = new Timer(initTime, 1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, start, false, 0, true);
timer.start();
help.hide();
}
private function start(evt:TimerEvent):void {
evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, start);
score.startTime();
//オセロの公式ルールに従い、黒石白石の初期配置を修正。(by Hamlet)
putPiece(2, 3, 3); //putPiece(1, 3, 3);
putPiece(1, 3, 4); //putPiece(2, 3, 4);
putPiece(2, 4, 4); //putPiece(1, 4, 4);
putPiece(1, 4, 3); //putPiece(2, 4, 3);
}
//盤面にコマを配置する
private function put(px:uint, py:uint):void {
if (map.getPoint(px, py)) {
if (map.getHint(px, py)) {
switch (player) {
case 1 :
putPiece(player, px, py);
break;
case 2 :
cpuPiece(player, px, py);
var timer:Timer = new Timer(cpuTime, 1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, cpuPut, false, 0, true);
timer.start();
break;
}
} else {
score.showMessage(Game.NO_POINT);
}
} else {
score.showMessage(Game.NO_POINT);
}
}
//盤面にコマを配置する(配置可能なマスに)
private function putPiece(p:uint, px:uint, py:uint):void {
var point:Point = pointList[px+py*pieces];
var xPos:uint = point.x;
var yPos:uint = point.y;
var id:uint = px+py*pieces;
var piece:Piece = new Piece();
addChild(piece);
piece.id = id;
piece.px = px;
piece.py = py;
piece.x = xPos;
piece.y = yPos;
pieceList[id] = piece;
piece.addEventListener(Game.PUT_COMPLETE, putComplete, false, 0, true);
piece.addEventListener(Game.TURN_COMPLETE, turnComplete, false, 0, true);
piece.put(p);
score.put(p);
map.put(p, px, py);
seput.play("put", 1);
hideHint();
pid ++;
manager.enable = false;
}
private function cpuPiece(p:uint, px:uint, py:uint):void {
cpu = {p: p, px: px, py: py};
}
private function cpuPut(evt:TimerEvent):void {
evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, cpuPut);
putPiece(cpu.p, cpu.px, cpu.py);
}
private function clearPieces():void {
for (var px:uint = 0; px < pieces; px++) {
for (var py:uint = 0; py < pieces; py++) {
var piece:Piece = pieceList[px+py*pieces];
if (piece) removeChild(piece);
piece = null;
}
}
pid = 0;
}
//コマ配置後の処理
private function putComplete(evt:Event):void {
switch (mode) {
case Game.INIT :
completed ++;
if (completed == 4) {
completed = 0;
mode = Game.PLAY;
score.showMessage(mode);
player = 2;
var timer:Timer = new Timer(startTime, 1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, prepare, false, 0, true);
timer.start();
}
break;
case Game.PLAY :
turn(evt.target.px, evt.target.py);
break;
}
}
//反転するコマ情報を取得する
private function turn(px:uint, py:uint):void {
var list:Array = map.getTurnList(player, px, py);
turns = list.length;
if (turns > 0) {
turnPieces(player, list);
seturn.play("turn", 1);
}
}
//コマを反転する
private function turnPieces(p:uint, list:Array):void {
for (var n:uint = 0; n < list.length; n++) {
var tx:uint = list[n].x;
var ty:uint = list[n].y;
var piece:Piece = pieceList[tx+ty*pieces];
piece.turn();
score.turn(p);
map.put(p, tx, ty);
}
}
//コマ反転後の処理
private function turnComplete(evt:Event):void {
completed ++;
if (completed == turns) {
completed = 0;
if (pid < pieces*pieces) {
prepare(null);
} else {
finish();
}
}
}
//攻守交代
private function prepare(evt:TimerEvent):void {
if (evt) evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, prepare);
player = player%2 + 1;
switch (player) {
case 1 :
score.showMessage(Game.PUT, player, passed2);
map.getBestPrio(player);
if (showHint()) {
if (!cursor) {
cursor = new Cursor();
addChild(cursor);
setCursor(4, 4);
manager.setCursor(4, 4);
}
manager.enable = true;
passed1 = false;
} else {
passed1 = true;
}
break;
case 2 :
score.showMessage(Game.PUT, player, passed1);
var best:Object = map.getBestPrio(player);
if (!isNaN(best.x) && !isNaN(best.y)) {
manager.autoCursor(best.x, best.y);
passed2 = false;
} else {
passed2 = true;
}
break;
}
if (passed1 && passed2) {
finish();
} else if ((player == 1 && passed1) || (player == 2 && passed2)) {
prepare(null);
}
}
private function moveCursor(evt:Event):void {
setCursor(evt.target.cx, evt.target.cy);
}
private function selectCursor(evt:Event):void {
put(evt.target.cx, evt.target.cy);
}
//盤面にカーソルを配置する
private function setCursor(cx:uint, cy:uint):void {
var point:Point = pointList[cx+cy*pieces];
var xPos:uint = point.x;
var yPos:uint = point.y;
cursor.x = xPos;
cursor.y = yPos;
}
//ヒントを表示する
private function showHint():Boolean {
var hint:uint = 0;
for (var px:uint = 0; px < pieces; px++) {
for (var py:uint = 0; py < pieces; py++) {
var point:Point = pointList[px+py*pieces];
if (map.getHint(px, py)) {
hint ++;
point.hint();
} else {
point.init();
}
}
}
if (hint > 0) {
return true;
} else {
return false;
}
}
//ヒントを非表示にする
private function hideHint():void {
for (var px:uint = 0; px < pieces; px++) {
for (var py:uint = 0; py < pieces; py++) {
var point:Point = pointList[px+py*pieces];
point.init();
}
}
}
//ゲーム終了の処理
private function finish():void {
mode = Game.FINISH;
score.showMessage(mode);
var timer:Timer = new Timer(finishTime, 1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, showHelp, false, 0, true);
timer.start();
score.stopTime();
player = 0;
passed1 = false;
passed2 = false;
}
private function showHelp(evt:TimerEvent):void {
evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, showHelp);
var scr:Array = score.getScore();
var p1:uint = scr[0];
var p2:uint = scr[1];
//twitter
result = String(p1) + ":" + String(p2);
if (p1 > p2) {
help.show("You win!");
sefanfare.play("fanfare", 1);
msgs = ["コンピュータに ", " で勝ったよ!"];
} else if (p1 == p2) {
help.show("draw");
seclaps.play("claps", 1);
msgs = ["コンピュータと ", " の引き分けでした。"];
} else {
help.show("You lose");
sefailure.play("failure", 1);
msgs = ["コンピュータに ", " で負けました..."];
}
removeChild(cursor);
cursor = null;
manager.help = Game.RESET;
}
private function resetSelect(evt:Event):void {
manager.help = Game.NO_HELP;
var timer:Timer = new Timer(resetTime, 1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, reset, false, 0, true);
timer.start();
help.hide();
}
private function draw():void {
graphics.beginFill(bColor);
graphics.drawRect(-2, -2, 340, 340);
graphics.endFill();
pointList = new Array();
for (var px:uint = 0; px < pieces; px++) {
for (var py:uint = 0; py < pieces; py++) {
var point:Point = new Point();
addChild(point);
var id:uint = px+py*pieces;
point.id = id;
pointList[id] = point;
point.x = 21 + 42*px;
point.y = 21 + 42*py;
point.init();
}
}
for (var cx:uint = 0; cx < 2; cx++) {
for (var cy:uint = 0; cy < 2; cy++) {
var corner:Shape = new Shape();
addChild(corner);
corner.graphics.beginFill(bColor);
corner.graphics.drawCircle(0, 0, 4);
corner.graphics.endFill();
corner.x = 84 + 168*cx;
corner.y = 84 + 168*cy;
}
}
//twitter
twitterBtn = new Btn();
addChild(twitterBtn);
twitterBtn.x = 365;
twitterBtn.y = 350;
twitterBtn.init({label: "twitter"});
twitterBtn.addEventListener(MouseEvent.CLICK, twitter, false, 0, true);
}
//twitter対応
private function twitter(evt:MouseEvent):void {
var msg:String = "";
switch (mode) {
case Game.INIT :
msg = "ゲームを開始します。";
break;
case Game.PLAY :
msg = "ゲーム中です。";
break;
case Game.FINISH :
msg = msgs[0] + result + msgs[1];
break;
}
navigateToURL(new URLRequest(twitterPath + escapeMultiByte(msg + tag)), "_blank");
}
}
//////////////////////////////////////////////////
// 盤面上のコマの位置を管理するクラス
//////////////////////////////////////////////////
class Map {
private static var pieces:uint = 8;
//空マップ
private var aMap:Array;
//盤面上のコマ配置マップ
private var bMap:Array;
//優先度マップ
private var pMap:Array;
//走査マップ
private var cMap:Array;
//ヒント表示マップ
private var hMap:Array;
//独自拡張部分。(by Hamlet)
private var Ai:AiManager;
public function Map() {
init();
}
private function init():void {
aMap = new Array();
aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
aMap.push([0, 0, 0, 0, 0, 0, 0, 0]);
bMap = copyMap(aMap);
cMap = copyMap(aMap);
pMap = new Array();
pMap.push([7, 0, 5, 6, 6, 5, 0, 7]);
pMap.push([0, 0, 2, 3, 3, 2, 0, 0]);
pMap.push([5, 2, 5, 4, 4, 5, 2, 5]);
pMap.push([6, 3, 4, 4 ,4, 4, 3, 6]);
pMap.push([6, 3, 4, 4 ,4, 4, 3, 6]);
pMap.push([5, 2, 5, 4, 4, 5, 2, 5]);
pMap.push([0, 0, 2, 3, 3, 2, 0, 0]);
pMap.push([7, 0, 5, 6, 6, 5, 0, 7]);
//独自拡張部分。AIクラスのインスタンス化。(by Hamlet)
Ai = new AiManager();
}
private function copyMap(list:Array):Array {
var map:Array = new Array();
for (var n:uint = 0; n < list.length; n++) {
map[n] = list[n].concat();
}
return map;
}
//コマの配置をマップに設定する
public function put(p:uint, x:uint, y:uint):void {
bMap[y][x] = p;
cMap[y][x] = p;
for (var cx:int = x-1; cx <= x+1; cx++) {
for (var cy:int = y-1; cy <= y+1; cy++) {
if (cx >= 0 && cx < pieces && cy >= 0 && cy < pieces) {
var player:Object = bMap[cy][cx];
player = (player == 0) ? "*" : player;
cMap[cy][cx] = player;
}
}
}
}
//配置可能なマスかどうかを判定する
public function getPoint(x:uint, y:uint):Boolean {
if (bMap[y][x] == 0) {
return true;
} else {
return false;
}
}
//走査対象のコマかどうかを判定する
private function getCheck(x:uint, y:uint):Boolean {
var check:Object = cMap[y][x];
if (check == "*") {
return true;
} else {
return false;
}
}
//ヒント表示するコマかどうかを判定する
public function getHint(x:uint, y:uint):Boolean {
var hint:Object = hMap[y][x];
if (hint == "*") {
return true;
} else {
return false;
}
}
//評価値の高いマスを取得する({x: 0, y: 0}で返す)
public function getBestPrio(p:uint):Object {
var px:Number = undefined;
var py:Number = undefined;
var ev:int = -9999;
var best:int = -9999;
var bestpos:Array = new Array(35);
var bestcnt:int = 0;
hMap = copyMap(aMap);
for (var x:uint = 0; x < pieces; x++) {
for (var y:uint = 0; y < pieces; y++) {
if (getCheck(x, y)) {
var turns:uint = getTurns(p, x, y);
if (turns > 0) {
hMap[y][x] = "*";
//独自拡張部分。思考エンジンをコールし評価値を得る。
ev = Ai.Think(bMap, p, x, y);
if (best < ev) {
//評価値がより大きい場合、bestを更新する。
bestcnt = 0;
bestpos[bestcnt++] = y * 8 + x;
best = ev;
} else if (best == ev) {
//bestと同じ評価値の場合、候補のリストに追加する。
bestpos[bestcnt++] = y * 8 + x;
}
}
}
}
}
var index:int = Math.floor (Math.random () * bestcnt)
px = bestpos[index] % 8;
py = (int)(bestpos[index] / 8);
return {x: px, y: py};
}
//指定したマスの8方向に対して反転できるコマ数を取得する
public function getTurns(p:uint, x:uint, y:uint):uint {
var turns:uint = 0;
for (var dx:int = -1; dx <= 1; dx++) {
for (var dy:int = -1; dy <= 1; dy++) {
if (dx == 0 && dy == 0) continue;
var px:int = x + dx;
var py:int = y + dy;
while (px >= 0 && px < pieces && py >= 0 && py < pieces) {
var player:uint = bMap[py][px];
if (player == 0) break;
if (player == p) {
if (dx != 0) {
turns += dx*(px - x) - 1;
} else {
turns += dy*(py - y) - 1;
}
break;
}
px += dx;
py += dy;
}
}
}
return turns;
}
//反転するコマ情報を取得する
public function getTurnList(p:uint, x:uint, y:uint):Array {
var list:Array = new Array();
for (var dx:int = -1; dx <= 1; dx++) {
for (var dy:int = -1; dy <= 1; dy++) {
if (dx == 0 && dy == 0) continue;
var px:int = x + dx;
var py:int = y + dy;
var checking:Boolean = true;
while (px >= 0 && px < pieces && py >= 0 && py < pieces) {
var player:uint = bMap[py][px];
if (player == 0) break;
if (player == p) {
if (checking) {
px = x + dx;
py = y + dy;
checking = false;
continue;
} else {
break;
}
}
if (!checking && player != p) {
list.push({x: px, y: py});
}
px += dx;
py += dy;
}
}
}
return list;
}
}
//////////////////////////////////////////////////
// コマの動きを管理するクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;
class Piece extends Sprite {
public var id:uint;
public var px:uint;
public var py:uint;
private var piece1:PieceShape;
private var piece2:PieceShape;
private var scale:Number = 1;
private var light:Shape;
private var _brightness:Number = 0;
public function Piece() {
draw();
}
public function put(p:uint):void {
id = p;
var piece:PieceShape = this["piece"+id];
addChild(piece);
piece.scaleX = piece.scaleY = scale = 1.6;
addEventListener(Event.ENTER_FRAME, putPiece, false, 0, true);
}
private function putPiece(evt:Event):void {
var piece:PieceShape = this["piece"+id];
scale -= 0.1;
piece.scaleX = piece.scaleY = scale;
if (scale <= 1) {
piece.scaleX = piece.scaleY = scale = 1;
removeEventListener(Event.ENTER_FRAME, putPiece);
dispatchEvent(new Event(Game.PUT_COMPLETE))
}
}
public function turn():void {
var old:PieceShape = this["piece"+id];
removeChild(old);
id = id%2 + 1;
var piece:PieceShape = this["piece"+id];
addChild(piece);
addChild(light);
var timer:Timer = new Timer(50, 6);
timer.addEventListener(TimerEvent.TIMER, turnPiece, false, 0, true);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, motion, false, 0, true);
timer.start();
}
private function turnPiece(evt:TimerEvent):void {
if (evt.target.currentCount == 4) {
evt.target.removeEventListener(TimerEvent.TIMER, turnPiece);
removeChild(light);
}
}
private function motion(evt:TimerEvent):void {
evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, motion);
brightness = 100;
addEventListener(Event.ENTER_FRAME, bright, false, 0, true);
}
private function bright(evt:Event):void {
brightness -= 20;
if (brightness <= 0) {
brightness = 0;
removeEventListener(Event.ENTER_FRAME, bright);
dispatchEvent(new Event(Game.TURN_COMPLETE))
}
}
private function draw():void {
graphics.beginFill(0x000000);
graphics.drawCircle(0, 0, 20);
graphics.endFill();
piece1 = new PieceShape(1);
piece2 = new PieceShape(2);
light = new Shape();
light.graphics.beginFill(0xFFFFFF);
light.graphics.drawCircle(0, 0, 20);
light.graphics.drawCircle(0, 0, 15);
light.graphics.endFill();
}
private function get brightness():Number {
return _brightness;
}
private function set brightness(param:Number):void {
_brightness = param;
ColorManager.brightOffset(this, _brightness);
}
}
//////////////////////////////////////////////////
// コマを描画するクラス
//////////////////////////////////////////////////
import flash.display.Shape;
import flash.geom.Matrix;
import flash.display.GradientType;
import flash.display.SpreadMethod;
import flash.display.InterpolationMethod;
class PieceShape extends Shape {
private var type:uint = 1;
private static var cList:Array = [[0x888888, 0x000000], [0xFFFFFF, 0xBBBBBB]];
private static var bList:Array = [0x444444, 0xDDDDDD];
public function PieceShape(t:uint) {
type = t;
draw();
}
private function draw():void {
var colors:Array = cList[type-1];
var alphas:Array = [1, 1];
var ratios:Array = [0, 255];
var matrix:Matrix = new Matrix();
matrix.createGradientBox(36, 36, 0.25*Math.PI, -18, -18);
graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix, SpreadMethod.PAD, InterpolationMethod.RGB, 0);
graphics.drawCircle(0, 0, 18);
graphics.endFill();
var bColor:uint = bList[type-1];
graphics.beginFill(bColor);
graphics.drawCircle(0, 0, 15);
graphics.endFill();
}
}
//////////////////////////////////////////////////
// マスを着色するクラス
//////////////////////////////////////////////////
import flash.display.Shape;
import flash.geom.ColorTransform;
class Point extends Shape {
public var id:uint;
private static var bColor:uint = 0x66CC00;
private static var cColor:uint = 0x66CCFF;
private static var bColorTrans:ColorTransform;
private static var cColorTrans:ColorTransform;
public function Point() {
draw();
}
public function init():void {
transform.colorTransform = bColorTrans;
}
public function hint():void {
transform.colorTransform = cColorTrans;
}
private function draw():void {
graphics.beginFill(0xFFFFFF);
graphics.drawRect(-20, -20, 40, 40);
graphics.endFill();
bColorTrans = new ColorTransform(0, 0, 0, 1, 0, 0, 0, 0);
bColorTrans.color = bColor;
cColorTrans = new ColorTransform(0, 0, 0, 1, 0, 0, 0, 0);
cColorTrans.color = cColor;
}
}
//////////////////////////////////////////////////
// 得点を管理するクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.filters.DropShadowFilter;
class Score extends Sprite {
private var pieces1:uint = 0;
private var pieces2:uint = 0;
private var score1:TextField;
private var score2:TextField;
private var message:TextField;
private var player:Array;
private var msgs:Object;
private var time:Time;
private var txt:TextField;
private static var bColor:uint = 0xFFFF00;
private static var sColor:uint = 0x000000;
private static var b1Color:uint = 0x66CC00;
private static var b2Color:uint = 0xFFFFFF;
private static var fontType:String = "_ゴシック";
//private static var initMsg:String = "ゲームを初期化しています。";
private static var initMsg:String = "Enterキー・上下左右キーで操作してください。";
private static var playMsg:String = "ゲームを開始します。";
private static var putMsg:String = "の番です。";
private static var passMsg:String = "はパス。";
private static var finishMsg:String = "ゲームは終了しました。";
private static var noPointMsg:String = "そのマスにはコマを置けません。";
public function Score() {
draw();
initialize();
}
private function initialize():void {
msgs = new Object();
msgs[Game.INIT] = initMsg;
msgs[Game.PLAY] = playMsg;
msgs[Game.PUT] = putMsg;
msgs[Game.FINISH] = finishMsg;
msgs[Game.NO_POINT] = noPointMsg;
player = new Array();
player[1] = "あなた";
player[2] = "コンピュータ";
time = new Time(txt);
}
public function init():void {
pieces1 = 0;
pieces2 = 0;
showScore();
}
public function put(p:uint):void {
this["pieces"+p] ++;
showScore();
}
public function turn(p:uint):void {
this["pieces"+p] ++;
var r:uint = p%2 + 1;
this["pieces"+r] --;
showScore();
}
private function showScore():void {
score1.text = String(pieces1);
score2.text = String(pieces2);
}
public function showMessage(mode:String, p:uint = 0, passed:Boolean = false):void {
switch (mode) {
case Game.PUT :
if (!passed) {
message.text = player[p] + msgs[mode];
} else {
var r:uint = p%2 + 1;
message.text = player[r] + passMsg + player[p] + msgs[mode];
}
break;
default :
message.text = msgs[mode];
break;
}
}
public function getScore():Array {
return [pieces1, pieces2];
}
public function startTime():void {
time.start();
}
public function stopTime():void {
time.stop();
}
public function resetTime():void {
time.reset();
}
private function draw():void {
graphics.beginFill(bColor);
graphics.drawRect(20, 56, 340, 24);
graphics.endFill();
graphics.beginFill(b1Color);
graphics.drawRoundRect(256, 0, 104, 44, 12);
graphics.endFill();
graphics.beginFill(b2Color);
graphics.drawRoundRect(258, 2, 100, 40, 8);
graphics.endFill();
var piece1:PieceShape = new PieceShape(1);
addChild(piece1);
piece1.x = 288;
piece1.y = 29;
piece1.width = piece1.height = 24;
var piece2:PieceShape = new PieceShape(2);
addChild(piece2);
piece2.x = 328;
piece2.y = 29;
piece2.width = piece2.height = 24;
var shade:DropShadowFilter = new DropShadowFilter(1, 90, sColor, 0.3, 2, 2, 2, 2, false, false);
filters = [shade];
drawText();
}
private function drawText():void {
var tf:TextFormat = new TextFormat();
tf.font = "_ゴシック";
tf.size = 12;
tf.align = TextFormatAlign.LEFT;
message = new TextField();
addChild(message);
message.x = 30;
message.y = 59;
message.width = 404;
message.height = 21;
message.type = TextFieldType.DYNAMIC;
message.selectable = false;
message.antiAliasType = AntiAliasType.ADVANCED;
message.defaultTextFormat = tf;
message.textColor = 0x000000;
var shade:DropShadowFilter = new DropShadowFilter(1, 90, sColor, 0.4, 2, 2, 2, 2, false, false);
var tfn:TextFormat = new TextFormat();
tfn.font = fontType;
tfn.size = 12;
tfn.align = TextFormatAlign.CENTER;
var name1:TextField = new TextField();
addChild(name1);
name1.x = 273;
name1.y = 1;
name1.width = 30;
name1.height = 19;
name1.type = TextFieldType.DYNAMIC;
name1.selectable = false;
//name1.embedFonts = true;
//name1.antiAliasType = AntiAliasType.ADVANCED;
name1.defaultTextFormat = tfn;
name1.textColor = 0x000000;
name1.text = "You";
name1.filters = [shade];
var name2:TextField = new TextField();
addChild(name2);
name2.x = 313;
name2.y = 1;
name2.width = 30;
name2.height = 19;
name2.type = TextFieldType.DYNAMIC;
name2.selectable = false;
//name2.embedFonts = true;
//name2.antiAliasType = AntiAliasType.ADVANCED;
name2.defaultTextFormat = tfn;
name2.textColor = 0x000000;
name2.text = "CPU";
name2.filters = [shade];
var tfc:TextFormat = new TextFormat();
tfc.font = fontType;
tfc.size = 14;
tfc.align = TextFormatAlign.CENTER;
score1 = new TextField();
addChild(score1);
score1.x = 273;
score1.y = 19;
score1.width = 30;
score1.height = 23;
score1.type = TextFieldType.DYNAMIC;
score1.selectable = false;
//score1.embedFonts = true;
//score1.antiAliasType = AntiAliasType.ADVANCED;
score1.defaultTextFormat = tfc;
score1.textColor = 0xFFFFFF;
score1.text = String(0);
score2 = new TextField();
addChild(score2);
score2.x = 313;
score2.y = 19;
score2.width = 30;
score2.height = 23;
score2.type = TextFieldType.DYNAMIC;
score2.selectable = false;
//score2.embedFonts = true;
//score2.antiAliasType = AntiAliasType.ADVANCED;
score2.defaultTextFormat = tfc;
score2.textColor = 0x000000;
score2.text = String(0);
var tft:TextFormat = new TextFormat();
tft.font = fontType;
tft.size = 16;
tft.align = TextFormatAlign.LEFT;
var timer:TextField = new TextField();
addChild(timer);
timer.x = 140;
timer.y = 18;
timer.width = 40;
timer.height = 21;
timer.type = TextFieldType.DYNAMIC;
timer.selectable = false;
//timer.embedFonts = true;
//timer.antiAliasType = AntiAliasType.ADVANCED;
timer.defaultTextFormat = tft;
timer.textColor = 0xFFFFFF;
timer.text = "Time";
txt = new TextField();
addChild(txt);
txt.x = 185;
txt.y = 18;
txt.width = 55;
txt.height = 21;
txt.type = TextFieldType.DYNAMIC;
txt.selectable = false;
//txt.embedFonts = true;
//txt.antiAliasType = AntiAliasType.ADVANCED;
txt.defaultTextFormat = tft;
txt.textColor = 0xFFFFFF;
txt.text = "00:00";
}
}
//////////////////////////////////////////////////
// タイマーを管理するクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.text.TextField;
import flash.utils.getTimer;
import flash.utils.Timer;
import flash.events.TimerEvent;
class Time extends Sprite {
private var target:TextField;
private var startTime:uint;
private var timer:Timer;
private var countTime:uint = 30;
public function Time(tg:TextField) {
target = tg;
}
public function start():void {
startTime = getTimer();
timer = new Timer(countTime);
timer.addEventListener(TimerEvent.TIMER, count, false, 0, true);
timer.start();
}
private function count(evt:TimerEvent):void {
var sec:uint = Math.floor((getTimer() - startTime)/1000);
var min:String = String(Math.floor(sec/60));
min = (uint(min) < 10) ? "0" + min : min;
var msec:String = String(sec%60);
msec = (uint(msec) < 10) ? "0" + msec : msec;
target.text = min + ":" + msec;
}
public function stop():void {
timer.removeEventListener(TimerEvent.TIMER, count);
}
public function reset():void {
target.text = "00:00";
}
}
//////////////////////////////////////////////////
// カーソル操作を管理するクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.events.Event;
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
class Manager extends Sprite {
private var board:Board;
private static var pieces:uint = 8;
public var cx:int;
public var cy:int;
private var tx:uint;
private var ty:uint;
private var cpu:Object;
private static var autoTime:uint = 200;
private var helpMode:String = "";
private var keyMode:Boolean = false;
public function Manager(b:Board) {
board = b;
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
}
private function init(evt:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
cpu = new Object();
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown, false, 0, true);
}
//カーソル位置を設定する
public function setCursor(x:uint, y:uint):void {
cx = x;
cy = y;
}
//キー操作の処理
private function keyDown(evt:KeyboardEvent):void {
if (helpMode) {
if (evt.keyCode == Keyboard.ENTER) {
dispatchEvent(new Event(helpMode));
}
}
if (keyMode) {
switch (evt.keyCode) {
case Keyboard.ENTER :
dispatchEvent(new Event(Game.SELECT));
break;
case Keyboard.LEFT :
cx --;
break;
case Keyboard.UP :
cy --;
break;
case Keyboard.RIGHT :
cx ++;
break;
case Keyboard.DOWN :
cy ++;
break;
}
if (cx > pieces - 1) cx = 0;
if (cx < 0) cx = pieces - 1;
if (cy > pieces - 1) cy = 0;
if (cy < 0) cy = pieces - 1;
dispatchEvent(new Event(Game.MOVE));
}
}
//カーソル位置を移動する
public function autoCursor(px:uint, py:uint):void {
tx = px;
ty = py;
var timer:Timer = new Timer(autoTime);
timer.addEventListener(TimerEvent.TIMER, moveCursor, false, 0, true);
timer.start();
}
private function moveCursor(evt:TimerEvent):void {
var mx:int = uint(tx > cx) - uint(tx < cx);
var my:int = uint(ty > cy) - uint(ty < cy);
if (mx != 0 || my != 0) {
cx += mx;
cy += my;
dispatchEvent(new Event(Game.MOVE));
if (cx == tx && cy == ty) {
evt.target.removeEventListener(TimerEvent.TIMER, moveCursor);
dispatchEvent(new Event(Game.SELECT));
}
}
}
public function set enable(param:Boolean):void {
keyMode = param;
}
public function set help(param:String):void {
helpMode = param;
}
}
//////////////////////////////////////////////////
// カーソルを描画するクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.display.Shape;
import flash.utils.Timer;
import flash.events.TimerEvent;
class Cursor extends Sprite {
private var id:uint = 0;
private var cursor0:Shape;
private var cursor1:Shape;
private static var bColor:uint = 0x66CC00;
private static var cColor:uint = 0x66CCFF;
public function Cursor() {
draw();
init();
}
private function init():void {
var cursor:Shape = this["cursor"+id];
addChild(cursor);
var timer:Timer = new Timer(250);
timer.addEventListener(TimerEvent.TIMER, change, false, 0, true);
timer.start();
}
private function change(evt:TimerEvent):void {
var old:Shape = this["cursor"+id];
removeChild(old);
id = (id+1)%2;
var cursor:Shape = this["cursor"+id];
addChild(cursor);
}
private function draw():void {
cursor0 = new Shape();
cursor0.graphics.beginFill(0xFFFFFF);
cursor0.graphics.moveTo(-21, -21);
cursor0.graphics.lineTo(-21, -6);
cursor0.graphics.lineTo(-18, -6);
cursor0.graphics.lineTo(-18, -18);
cursor0.graphics.lineTo(-6, -18);
cursor0.graphics.lineTo(-6, -21);
cursor0.graphics.lineTo(-21, -21);
cursor0.graphics.moveTo(21, -21);
cursor0.graphics.lineTo(21, -6);
cursor0.graphics.lineTo(18, -6);
cursor0.graphics.lineTo(18, -18);
cursor0.graphics.lineTo(6, -18);
cursor0.graphics.lineTo(6, -21);
cursor0.graphics.lineTo(21, -21);
cursor0.graphics.moveTo(-21, 21);
cursor0.graphics.lineTo(-21, 6);
cursor0.graphics.lineTo(-18, 6);
cursor0.graphics.lineTo(-18, 18);
cursor0.graphics.lineTo(-6, 18);
cursor0.graphics.lineTo(-6, 21);
cursor0.graphics.lineTo(-21, 21);
cursor0.graphics.moveTo(21, 21);
cursor0.graphics.lineTo(21, 6);
cursor0.graphics.lineTo(18, 6);
cursor0.graphics.lineTo(18, 18);
cursor0.graphics.lineTo(6, 18);
cursor0.graphics.lineTo(6, 21);
cursor0.graphics.lineTo(21, 21);
cursor0.graphics.endFill();
cursor1 = new Shape();
cursor1.graphics.beginFill(0xFFFFFF);
cursor1.graphics.moveTo(-22, -22);
cursor1.graphics.lineTo(-22, -7);
cursor1.graphics.lineTo(-19, -7);
cursor1.graphics.lineTo(-19, -19);
cursor1.graphics.lineTo(-7, -19);
cursor1.graphics.lineTo(-7, -22);
cursor1.graphics.lineTo(-22, -22);
cursor1.graphics.moveTo(22, -22);
cursor1.graphics.lineTo(22, -7);
cursor1.graphics.lineTo(19, -7);
cursor1.graphics.lineTo(19, -19);
cursor1.graphics.lineTo(7, -19);
cursor1.graphics.lineTo(7, -22);
cursor1.graphics.lineTo(22, -22);
cursor1.graphics.moveTo(-22, 22);
cursor1.graphics.lineTo(-22, 7);
cursor1.graphics.lineTo(-19, 7);
cursor1.graphics.lineTo(-19, 19);
cursor1.graphics.lineTo(-7, 19);
cursor1.graphics.lineTo(-7, 22);
cursor1.graphics.lineTo(-22, 22);
cursor1.graphics.moveTo(22, 22);
cursor1.graphics.lineTo(22, 7);
cursor1.graphics.lineTo(19, 7);
cursor1.graphics.lineTo(19, 19);
cursor1.graphics.lineTo(7, 19);
cursor1.graphics.lineTo(7, 22);
cursor1.graphics.lineTo(22, 22);
cursor1.graphics.endFill();
}
}
//////////////////////////////////////////////////
// ヘルプ表示を管理するクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.filters.GlowFilter;
class Help extends Sprite {
private var amplitude:Number = 0;
private var scale:Number = 1;
private static var targetScale:Number = 2;
private static var deceleration:Number = 0.5;
private static var friction:Number = 0.6;
private var txt:TextField;
private static var tColor:uint = 0x000000;
private static var gColor:uint = 0xFFFFFF;
private static var fontType:String = "_ゴシック";
public function Help() {
draw();
hide();
}
public function hide():void {
visible = false;
}
public function show(help:String):void {
txt.text = help;
visible = true;
amplitude = 0;
scale = 1;
addEventListener(Event.ENTER_FRAME, elastic, false, 0, true);
}
private function elastic(evt:Event):void {
amplitude += targetScale - scale;
scale += amplitude*friction;
amplitude *= deceleration;
scaleX = scaleY = scale;
if (Math.abs(targetScale - scale) < 0.005 && Math.abs(amplitude) < 0.001) {
scaleX = scaleY = targetScale;
removeEventListener(Event.ENTER_FRAME, elastic);
}
}
private function draw():void {
var tf:TextFormat = new TextFormat();
tf.font = fontType;
tf.size = 32;
tf.align = TextFormatAlign.CENTER;
txt = new TextField();
addChild(txt);
txt.x = -75;
txt.y = -19;
txt.width = 150;
txt.height = 39;
txt.type = TextFieldType.DYNAMIC;
txt.selectable = false;
//txt.embedFonts = true;
//txt.antiAliasType = AntiAliasType.ADVANCED;
txt.defaultTextFormat = tf;
txt.textColor = tColor;
var glow:GlowFilter = new GlowFilter(gColor, 1, 10, 10, 10, 1, false, false);
txt.filters = [glow];
}
}
//////////////////////////////////////////////////
// ColorManagerクラス
//////////////////////////////////////////////////
import flash.display.DisplayObject;
import flash.geom.ColorTransform;
import flash.filters.ColorMatrixFilter;
class ColorManager {
private static var rs:Number = 0.3086;
private static var gs:Number = 0.6094;
private static var bs:Number = 0.0820;
public function ColorManager() {
}
public static function brightOffset(target:DisplayObject, param:Number):void {
target.transform.colorTransform = getBrightOffset(param);
}
private static function getBrightOffset(param:Number):ColorTransform {
var percent:Number = 1;
var offset:Number = param*2.55;
var colorTrans:ColorTransform = new ColorTransform(0, 0, 0, 1, 0, 0, 0, 0);
colorTrans.redMultiplier = percent;
colorTrans.greenMultiplier = percent;
colorTrans.blueMultiplier = percent;
colorTrans.redOffset = offset;
colorTrans.greenOffset = offset;
colorTrans.blueOffset = offset;
colorTrans.alphaMultiplier = 1;
colorTrans.alphaOffset = 0;
return colorTrans;
}
public static function saturation(target:DisplayObject, param:Number):void {
target.filters = [getSaturation(param)];
}
private static function getSaturation(param:Number):ColorMatrixFilter {
var colorMatrix:ColorMatrixFilter = new ColorMatrixFilter();
var p:Number = param*0.01;
var r:Number = (1 - p)*rs;
var g:Number = (1 - p)*gs;
var b:Number = (1 - p)*bs;
var matrix:Array = [r + p, g, b, 0, 0, r, g + p, b, 0, 0, r, g, b + p, 0, 0, 0, 0, 0, 1, 0];
colorMatrix.matrix = matrix;
return colorMatrix;
}
}
//////////////////////////////////////////////////
// SoundEffectクラス
//////////////////////////////////////////////////
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
import flash.events.ProgressEvent;
import flash.net.URLRequest;
class SoundEffect extends EventDispatcher {
private static var soundList:Object;
private var sound:Sound;
private var channel:SoundChannel;
private static var initialized:Boolean = false;
private var volume:Number;
private var looping:Boolean = false;
public function SoundEffect() {
if (!initialized) initialize();
}
private static function initialize():void {
initialized = true;
soundList = new Object();
}
public function init(Snd:Class, id:String):void {
var snd:Sound = new Snd();
soundList[id] = snd;
}
public function load(file:String, id:String):void {
var snd:Sound = new Sound();
snd.load(new URLRequest(file));
snd.addEventListener(ProgressEvent.PROGRESS, progress, false, 0, true);
snd.addEventListener(Event.COMPLETE, loaded, false, 0, true);
soundList[id] = snd;
}
public function play(id:String, vol:Number, loop:Boolean = false):void {
if (channel != null) channel.stop();
sound = soundList[id];
volume = vol;
looping = loop;
channel = sound.play();
var transform:SoundTransform = channel.soundTransform;
transform.volume = volume;
channel.soundTransform = transform;
if (looping) {
channel.addEventListener(Event.SOUND_COMPLETE, complete, false, 0, true);
}
}
public function stop():void {
if (channel != null) {
channel.stop();
channel.removeEventListener(Event.SOUND_COMPLETE, complete);
}
}
private function progress(evt:ProgressEvent):void {
dispatchEvent(evt);
}
private function loaded(evt:Event):void {
dispatchEvent(evt);
}
private function complete(evt:Event):void {
channel.removeEventListener(Event.SOUND_COMPLETE, complete);
if (looping) {
channel = sound.play(0);
channel.addEventListener(Event.SOUND_COMPLETE, complete, false, 0, true);
var transform:SoundTransform = channel.soundTransform;
transform.volume = volume;
channel.soundTransform = transform;
}
}
}
//////////////////////////////////////////////////
// Btnクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.display.Shape;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.filters.GlowFilter;
import flash.events.MouseEvent;
class Btn extends Sprite {
public var id:uint;
private var shade:Shape;
private var bottom:Shape;
private var light:Shape;
private var base:Shape;
private var txt:TextField;
private var label:String = "";
private static var fontType:String = "_ゴシック";
private var _width:uint = 60;
private static var _height:uint = 20;
private static var corner:uint = 5;
private var type:uint = 1;
private static var bColor:uint = 0xFFFFFF;
private static var sColor:uint = 0x000000;
private static var upColor:uint = 0x666666;
private static var overColor:uint = 0x333333;
private static var offColor:uint = 0x999999;
private static var gColor:uint = 0x0099FF;
private var blueGlow:GlowFilter;
private var shadeGlow:GlowFilter;
private var _clicked:Boolean = false;
private var _enabled:Boolean = true;
public function Btn() {
}
public function init(option:Object):void {
if (option.id != undefined) id = option.id;
if (option.label != undefined) label = option.label;
if (option.width != undefined) _width = option.width;
if (option.type != undefined) type = option.type;
draw();
}
private function draw():void {
switch (type) {
case 1 :
bColor = 0xFFFFFF;
sColor = 0x000000;
upColor = 0x666666;
overColor = 0x333333;
offColor = 0x999999;
break;
case 2 :
bColor = 0x000000;
sColor = 0xFFFFFF;
upColor = 0x666666;
overColor = 0x999999;
offColor = 0x333333;
break;
}
blueGlow = new GlowFilter(gColor, 0.6, 5, 5, 2, 3, false, true);
shadeGlow = new GlowFilter(sColor, 0.3, 4, 4, 2, 3, false, true);
shade = new Shape();
bottom = new Shape();
light = new Shape();
base = new Shape();
txt = new TextField();
addChild(shade);
addChild(bottom);
addChild(light);
addChild(base);
addChild(txt);
createBase(shade, _width, _height, corner, sColor);
shade.filters = [shadeGlow];
createBase(bottom, _width, _height, corner, sColor, 0.3);
createBase(light, _width, _height, corner, gColor);
light.filters = [blueGlow];
createBase(base, _width, _height, corner, bColor);
txt.x = -_width*0.5;
txt.y = -_height*0.5;
txt.width = _width;
txt.height = _height - 1;
txt.type = TextFieldType.DYNAMIC;
txt.selectable = false;
//txt.embedFonts = true;
//txt.antiAliasType = AntiAliasType.ADVANCED;
var tf:TextFormat = new TextFormat();
tf.font = fontType;
tf.size = 12;
tf.align = TextFormatAlign.CENTER;
txt.defaultTextFormat = tf;
txt.text = label;
enabled = true;
mouseChildren = false;
}
private function rollOver(evt:MouseEvent):void {
_over();
}
private function rollOut(evt:MouseEvent):void {
_up();
}
private function press(evt:MouseEvent):void {
_down();
}
private function release(evt:MouseEvent):void {
_up();
}
private function click(evt:MouseEvent):void {
}
private function _up():void {
txt.y = -_height*0.5;
txt.textColor = upColor;
base.y = -1;
light.visible = false;
light.y = -1;
}
private function _over():void {
txt.y = -_height*0.5;
txt.textColor = overColor;
base.y = -1;
light.visible = true;
light.y = -1;
}
private function _down():void {
txt.y = -_height*0.5 + 1;
txt.textColor = overColor;
base.y = 0;
light.visible = true;
light.y = 0;
}
private function _off():void {
txt.y = -_height*0.5 + 1;
txt.textColor = offColor;
base.y = 0;
light.visible = false;
light.y = 0;
}
public function get clicked():Boolean {
return _clicked;
}
public function set clicked(param:Boolean):void {
_clicked = param;
enabled = !_clicked;
if (_clicked) {
_down();
} else {
_up();
}
}
public function get enabled():Boolean {
return _enabled;
}
public function set enabled(param:Boolean):void {
_enabled = param;
buttonMode = _enabled;
mouseEnabled = _enabled;
useHandCursor = _enabled;
if (_enabled) {
_up();
addEventListener(MouseEvent.MOUSE_OVER, rollOver, false, 0, true);
addEventListener(MouseEvent.MOUSE_OUT, rollOut, false, 0, true);
addEventListener(MouseEvent.MOUSE_DOWN, press, false, 0, true);
addEventListener(MouseEvent.MOUSE_UP, release, false, 0, true);
addEventListener(MouseEvent.CLICK, click, false, 0, true);
} else {
_off();
removeEventListener(MouseEvent.MOUSE_OVER, rollOver);
removeEventListener(MouseEvent.MOUSE_OUT, rollOut);
removeEventListener(MouseEvent.MOUSE_DOWN, press);
removeEventListener(MouseEvent.MOUSE_UP, release);
removeEventListener(MouseEvent.CLICK, click);
}
}
private function createBase(target:Shape, w:uint, h:uint, c:uint, color:uint, alpha:Number = 1):void {
target.graphics.beginFill(color, alpha);
target.graphics.drawRoundRect(-w*0.5, -h*0.5, w, h, c*2);
target.graphics.endFill();
}
}
//////////////////////////////////////////////////
// AI用共通const定義 (by Hamlet)
//////////////////////////////////////////////////
class AiHeader {
//石色定義
public static const BLACK:int = -1;
public static const WHITE:int = 1;
public static const EMPTY:int = 0;
public static const DUMMY:int = 9;
//盤面ポジション定義
// A B C D E F G H
// 1) 10 11 12 13 14 15 16 17
// 2) 19 20 21 22 23 24 25 26
// 3) 28 29 30 31 32 33 34 35
// 4) 37 38 39 40 41 42 43 44
// 5) 46 47 48 49 50 51 52 53
// 6) 55 56 57 58 59 60 61 62
// 7) 64 65 66 67 68 69 70 71
// 8) 73 74 75 76 77 78 79 80
public static const A1:int = 10;
public static const B1:int = 11;
public static const C1:int = 12;
public static const D1:int = 13;
public static const E1:int = 14;
public static const F1:int = 15;
public static const G1:int = 16;
public static const H1:int = 17;
public static const A2:int = 19;
public static const B2:int = 20;
public static const C2:int = 21;
public static const D2:int = 22;
public static const E2:int = 23;
public static const F2:int = 24;
public static const G2:int = 25;
public static const H2:int = 26;
public static const A3:int = 28;
public static const B3:int = 29;
public static const C3:int = 30;
public static const D3:int = 31;
public static const E3:int = 32;
public static const F3:int = 33;
public static const G3:int = 34;
public static const H3:int = 35;
public static const A4:int = 37;
public static const B4:int = 38;
public static const C4:int = 39;
public static const D4:int = 40;
public static const E4:int = 41;
public static const F4:int = 42;
public static const G4:int = 43;
public static const H4:int = 44;
public static const A5:int = 46;
public static const B5:int = 47;
public static const C5:int = 48;
public static const D5:int = 49;
public static const E5:int = 50;
public static const F5:int = 51;
public static const G5:int = 52;
public static const H5:int = 53;
public static const A6:int = 55;
public static const B6:int = 56;
public static const C6:int = 57;
public static const D6:int = 58;
public static const E6:int = 59;
public static const F6:int = 60;
public static const G6:int = 61;
public static const H6:int = 62;
public static const A7:int = 64;
public static const B7:int = 65;
public static const C7:int = 66;
public static const D7:int = 67;
public static const E7:int = 68;
public static const F7:int = 69;
public static const G7:int = 70;
public static const H7:int = 71;
public static const A8:int = 73;
public static const B8:int = 74;
public static const C8:int = 75;
public static const D8:int = 76;
public static const E8:int = 77;
public static const F8:int = 78;
public static const G8:int = 79;
public static const H8:int = 80;
//その他、定数定義
public static const FASTESTFIRST:int = 8;
public static const EVALUE_FIRST:int = 3;
public static const INFINITY:int = 128;
public static const MIDGAME_DEPTH:int = 4; //中盤4手読み
public static const ENDGAME_DEPTH:int = 12; //終盤12手読み
}
//////////////////////////////////////////////////
// 盤面の評価値を算出するクラス (by Hamlet)
//////////////////////////////////////////////////
class AiManager extends AiHeader {
//CPU思考用・仮想ボード配列
private var ban:AiBoard = new AiBoard();
//CPU思考用・先読み処理
private var Search:SearchEngine = new SearchEngine();
//機能: 指定の場所(x, y)に石を置いた場合の評価値を計算する
//備考: 評価値計算ロジックに合わせるため、bMapの2次元盤面データをvtBoard1次元盤面配列に変換する。
public function Think(bMap:Array, p:int , x:int , y:int):int {
var nPos:int = 0, nCol:int=EMPTY;
var nVal:int = 0, nTurn:int = 0;
var nEmpties:int = 0, nDepth:int = MIDGAME_DEPTH;
var i:int, j:int;
var board:Array = ban.board;
var bestmove:Array = [0];
var discdiff:int = 0;
var strX:Array = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'];//debug用
var strY:Array = ['1', '2', '3', '4', '5', '6', '7', '8'];//debug用
//仮想盤面(vtBoard)に現在の盤面(bMap)の内容をセットする
for (i = 0; i < 91; i++) {
board[i] = DUMMY;
}
for (i = 0; i < 8; i++) {
for (j = 0; j < 8; j++) {
nPos = (i + 1) * 9 + j + 1;
switch (bMap[i][j]) {
case 1:
if (p == 1) {
board[nPos] = BLACK;
discdiff++;
}
else {
board[nPos] = WHITE;
discdiff--;
}
break;
case 2:
if (p == 1) {
board[nPos] = WHITE;
discdiff--;
}
else {
board[nPos] = BLACK;
discdiff++;
}
break;
default:
board[nPos] = EMPTY;
nEmpties++;
}
}
}
//仮想盤面(9*10+1)の座標に変換
nPos = (y + 1) * 9 + x + 1;
if (nEmpties > ENDGAME_DEPTH) {
//評価関数による評価値算出
if (nDepth >= nEmpties) nDepth = nEmpties - 1;
nVal = Search.midGameThink(ban, BLACK, nEmpties, discdiff, nPos, nDepth) & 0xFFFFFFFE;
}
else {
//終盤読み切りによる最終スコア算出
nVal = Search.endGameThink(ban, BLACK, nEmpties, discdiff, nPos);
}
return nVal;
}
}
//////////////////////////////////////////////////
// 盤面の空所を記録するリスト (by Hamlet)
//////////////////////////////////////////////////
class EmptyList {
public var square:int;
public var pred:EmptyList;
public var succ:EmptyList;
}
//////////////////////////////////////////////////
// AI用盤面管理クラス。高速処理用に別途用意。 (by Hamlet)
//////////////////////////////////////////////////
class AiBoard extends AiHeader {
public var board:Array = new Array(91);
public var flipStack:Array = new Array(1200);
public var flipStackP:int = 0;
public var emHead:EmptyList = new EmptyList();
public var ems:Array = new Array(60);
private const dirMask:Array = [
0,0,0,0,0,0,0,0,0,
0,81,81,87,87,87,87,22,22,
0,81,81,87,87,87,87,22,22,
0,121,121,255,255,255,255,182,182,
0,121,121,255,255,255,255,182,182,
0,121,121,255,255,255,255,182,182,
0,121,121,255,255,255,255,182,182,
0,41,41,171,171,171,171,162,162,
0,41,41,171,171,171,171,162,162,
0,0,0,0,0,0,0,0,0,0
];
public function undoFlips( flipCount:int, oppcol:int ):void {
if ( (flipCount & 1) != 0 ) {
flipCount--;
board[flipStack[--flipStackP]] = oppcol;
}
while ( flipCount > 0 ) {
flipCount -= 2;
board[flipStack[--flipStackP]] = oppcol;
board[flipStack[--flipStackP]] = oppcol;
}
}
public function anyFlips( sqnum:int, color:int ):Boolean {
var dir:int = dirMask[sqnum];
if (board[sqnum] != EMPTY)
return false;
if ( (dir & 128) != 0 )
if ( anyDrctnlFlips( sqnum, -10, color ) > 0) return true;
if ( (dir & 64) != 0 )
if ( anyDrctnlFlips( sqnum, 10, color ) > 0) return true;
if ( (dir & 32) != 0 )
if ( anyDrctnlFlips( sqnum, -9, color ) > 0) return true;
if ( (dir & 16) != 0 )
if ( anyDrctnlFlips( sqnum, 9, color ) > 0) return true;
if ( (dir & 8) != 0 )
if ( anyDrctnlFlips( sqnum, -8, color ) > 0) return true;
if ( (dir & 4) != 0 )
if ( anyDrctnlFlips( sqnum, 8, color ) > 0) return true;
if ( (dir & 2) != 0 )
if ( anyDrctnlFlips( sqnum, -1, color ) > 0) return true;
if ( (dir & 1) != 0 )
if ( anyDrctnlFlips( sqnum, 1, color ) > 0) return true;
return false;
}
private function anyDrctnlFlips( sqnum:int, inc:int, color:int ):int {
var pos:int = sqnum + inc;
var oppcol:int = -color;
if( board[pos] == oppcol ){
pos += inc;
if( board[pos] == oppcol ){
pos += inc;
if( board[pos] == oppcol ){
pos += inc;
if( board[pos] == oppcol ){
pos += inc;
if( board[pos] == oppcol ){
pos += inc;
if( board[pos] == oppcol ){
pos += inc;
}
}
}
}
}
if( board[pos] == color ) return 1;
}
return 0;
}
public function countFlips( sqnum:int, color:int ):int {
var count:int = 0;
var dir:int = dirMask[sqnum];
switch (dir) {
case 81: // A1 A2 B1 B2
count += ctDrctnlFlips( sqnum, +1, color );
count += ctDrctnlFlips( sqnum, +10, color );
count += ctDrctnlFlips( sqnum, +9, color );
break;
case 22: // G1 G2 H1 H2
count += ctDrctnlFlips( sqnum, -1, color );
count += ctDrctnlFlips( sqnum, +8, color );
count += ctDrctnlFlips( sqnum, +9, color );
break;
case 41: // A7 A8 B7 B8
count += ctDrctnlFlips( sqnum, -9, color );
count += ctDrctnlFlips( sqnum, -8, color );
count += ctDrctnlFlips( sqnum, +1, color );
break;
case 162:// G7 G8 H7 H8
count += ctDrctnlFlips( sqnum, -9, color );
count += ctDrctnlFlips( sqnum, -10, color );
count += ctDrctnlFlips( sqnum, -1, color );
break;
case 87: // C1 C2 D1 D2 E1 E2 F1 F2
count += ctDrctnlFlips( sqnum, -1, color );
count += ctDrctnlFlips( sqnum, +8, color );
count += ctDrctnlFlips( sqnum, +9, color );
count += ctDrctnlFlips( sqnum, +10, color );
count += ctDrctnlFlips( sqnum, +1, color );
break;
case 121:// A3 A4 A5 A6 B3 B4 B5 B6
count += ctDrctnlFlips( sqnum, -9, color );
count += ctDrctnlFlips( sqnum, -8, color );
count += ctDrctnlFlips( sqnum, +1, color );
count += ctDrctnlFlips( sqnum, +10, color );
count += ctDrctnlFlips( sqnum, +9, color );
break;
case 182:// G3 G4 G5 G6 H3 H4 H5 H6
count += ctDrctnlFlips( sqnum, -9, color );
count += ctDrctnlFlips( sqnum, -10, color );
count += ctDrctnlFlips( sqnum, -1, color );
count += ctDrctnlFlips( sqnum, +8, color );
count += ctDrctnlFlips( sqnum, +9, color );
break;
case 171:// C7 C8 D7 D8 E7 E8 F7 F8
count += ctDrctnlFlips( sqnum, -1, color );
count += ctDrctnlFlips( sqnum, -10, color );
count += ctDrctnlFlips( sqnum, -9, color );
count += ctDrctnlFlips( sqnum, -8, color );
count += ctDrctnlFlips( sqnum, +1, color );
break;
case 255:// C3 C4 C5 C6 D3 D4 D5 D6 E3 E4 E5 E6 F3 F4 F5 F6
count += ctDrctnlFlips( sqnum, -10, color );
count += ctDrctnlFlips( sqnum, -9, color );
count += ctDrctnlFlips( sqnum, -8, color );
count += ctDrctnlFlips( sqnum, -1, color );
count += ctDrctnlFlips( sqnum, +1, color );
count += ctDrctnlFlips( sqnum, +8, color );
count += ctDrctnlFlips( sqnum, +9, color );
count += ctDrctnlFlips( sqnum, +10, color );
break;
}
return count;
}
private function ctDrctnlFlips( sqnum:int, inc:int, color:int ):int {
var pos:int = sqnum + inc;
var oppcol:int = -color;
if( board[pos] == oppcol ){
pos += inc;
if( board[pos] == oppcol ){
pos += inc;
if( board[pos] == oppcol ){
pos += inc;
if( board[pos] == oppcol ){
pos += inc;
if( board[pos] == oppcol ){
pos += inc;
if( board[pos] == oppcol ){
if( board[pos + inc] == color ) return 6;
}
else if( board[pos] == color ) return 5;
}
else if( board[pos] == color ) return 4;
}
else if( board[pos] == color ) return 3;
}
else if( board[pos] == color ) return 2;
}
else if( board[pos] == color ) return 1;
}
return 0;
}
public function doFlips( sqnum:int, color:int ):int {
var dir:int = dirMask[sqnum];
var OldFlipStackP:int = flipStackP;
switch (dir) {
case 81: // A1 A2 B1 B2
drctnlFlips( sqnum, +1, color );
drctnlFlips( sqnum, +10, color );
drctnlFlips( sqnum, +9, color );
break;
case 22: // G1 G2 H1 H2
drctnlFlips( sqnum, -1, color );
drctnlFlips( sqnum, +8, color );
drctnlFlips( sqnum, +9, color );
break;
case 41: // A7 A8 B7 B8
drctnlFlips( sqnum, -9, color );
drctnlFlips( sqnum, -8, color );
drctnlFlips( sqnum, +1, color );
break;
case 162: // G7 G8 H7 H8
drctnlFlips( sqnum, -9, color );
drctnlFlips( sqnum, -10, color );
drctnlFlips( sqnum, -1, color );
break;
case 87: // C1 C2 D1 D2 E1 E2 F1 F2
drctnlFlips( sqnum, -1, color );
drctnlFlips( sqnum, +8, color );
drctnlFlips( sqnum, +9, color );
drctnlFlips( sqnum, +10, color );
drctnlFlips( sqnum, +1, color );
break;
case 121: // A3 A4 A5 A6 B3 B4 B5 B6
drctnlFlips( sqnum, -9, color );
drctnlFlips( sqnum, -8, color );
drctnlFlips( sqnum, +1, color );
drctnlFlips( sqnum, +10, color );
drctnlFlips( sqnum, +9, color );
break;
case 182: // G3 G4 G5 G6 H3 H4 H5 H6
drctnlFlips( sqnum, -9, color );
drctnlFlips( sqnum, -10, color );
drctnlFlips( sqnum, -1, color );
drctnlFlips( sqnum, +8, color );
drctnlFlips( sqnum, +9, color );
break;
case 171: // C7 C8 D7 D8 E7 E8 F7 F8
drctnlFlips( sqnum, -1, color );
drctnlFlips( sqnum, -10, color );
drctnlFlips( sqnum, -9, color );
drctnlFlips( sqnum, -8, color );
drctnlFlips( sqnum, +1, color );
break;
case 255: // C3 C4 C5 C6 D3 D4 D5 D6 E3 E4 E5 E6 F3 F4 F5 F6
drctnlFlips( sqnum, -10, color );
drctnlFlips( sqnum, -9, color );
drctnlFlips( sqnum, -8, color );
drctnlFlips( sqnum, -1, color );
drctnlFlips( sqnum, +1, color );
drctnlFlips( sqnum, +8, color );
drctnlFlips( sqnum, +9, color );
drctnlFlips( sqnum, +10, color );
break;
}
return flipStackP - OldFlipStackP;
}
private function drctnlFlips( sqnum:int, inc:int, color:int ):void {
var pos:int = sqnum + inc;
var sq:int = board[pos];
var oppcol:int = -color;
if( sq == oppcol ) {
sq = board[pos += inc];
if( sq == oppcol ) {
sq = board[pos += inc];
if( sq == oppcol ) {
sq = board[pos += inc];
if( sq == oppcol ) {
sq = board[pos += inc];
if( sq == oppcol ) {
sq = board[pos += inc];
if( sq == oppcol ) {
if( board[ pos + inc] != color ) return;
board[pos] = color;
flipStack[ flipStackP++ ] = pos;
}
else if (sq != color) return;
pos -= inc;
board[pos] = color;
flipStack[ flipStackP++ ] = pos;
}
else if (sq != color) return;
pos -= inc;
board[pos] = color;
flipStack[ flipStackP++ ] = pos;
}
else if (sq != color) return;
pos -= inc;
board[pos] = color;
flipStack[ flipStackP++ ] = pos;
}
else if (sq != color) return;
pos -= inc;
board[pos] = color;
flipStack[ flipStackP++ ] = pos;
}
else if (sq != color) return;
pos -= inc;
board[pos] = color;
flipStack[ flipStackP++ ] = pos;
}
}
}
//////////////////////////////////////////////////
// 盤面の探索を行うクラス (by Hamlet)
// 先読みを実行する探索処理用クラス
//////////////////////////////////////////////////
class SearchEngine extends AiHeader {
private var evalue:Evaluate;
private const worst2best:Array = [
20, 25, 65, 70,
11, 16, 19, 26, 64, 71, 74, 79,
21, 24, 29, 34, 56, 61, 66, 69,
22, 23, 38, 43, 47, 52, 67, 68,
31, 32, 39, 42, 48, 51, 58, 59,
13, 14, 37, 44, 46, 53, 76, 77,
30, 33, 57, 60,
12, 15, 28, 35, 55, 62, 75, 78,
10, 17, 73, 80
];
public function SearchEngine() {
evalue = new Evaluate();
}
//指定の場所に石を打った場合の最終スコアを算出する。
public function endGameThink( ban:AiBoard, color:int, empties:int, discdiff:int, sqnum:int ):int {
var oppcol:int = -color;
var flipped:int, score:int;
var board:Array = ban.board;
var square:Array = [0];
flipped = ban.doFlips( sqnum, color );
board[sqnum] = color;
score = -endSolve( ban, square, oppcol, empties-1, -discdiff-(flipped*2)-1 );
ban.undoFlips( flipped, oppcol );
board[sqnum] = EMPTY;
return score;
}
//指定の場所に石を打った場合の盤面評価値を算出する。
public function midGameThink( ban:AiBoard, color:int, empties:int, discdiff:int, sqnum:int, depth:int ):int {
var oppcol:int = -color;
var flipped:int, score:int;
var board:Array = ban.board;
var square:Array = [0];
flipped = ban.doFlips( sqnum, color );
board[sqnum] = color;
score = -midGame( ban, square, oppcol, empties-1, -discdiff-(flipped*2)-1, depth-1 );
ban.undoFlips( flipped, oppcol );
board[sqnum] = EMPTY;
return score;
}
//ゲームの木の探索前の準備処理 (空き場所リストの作成)
private function prepareToSolve( ban:AiBoard ):void {
var i:int, j:int, sqnum:int;
var board:Array = ban.board;
var Ems:Array = ban.ems;
j = 0;
var EmPtr:EmptyList = ban.emHead;
for (i = (60-1); i >= 0; i--) {
sqnum = worst2best[i];
if ( board[sqnum] == EMPTY ) {
Ems[j] = new EmptyList();
EmPtr.succ = Ems[j];
Ems[j].pred = EmPtr;
j++;
EmPtr = EmPtr.succ;
EmPtr.square = sqnum;
}
}
EmPtr.succ = null;
}
//指定盤面に対する最善手と最終スコアを返す。
private function endSolve ( ban:AiBoard, bestmove:Array, color:int, empties:int, discdiff:int ):int {
prepareToSolve(ban);
//終盤探索
if ( empties > FASTESTFIRST ) {
return fastestFirstEndSolve( ban, bestmove, -64, +64, color, empties, discdiff, 1 );
}
else {
return alphaBetaEndSolve( ban, bestmove, -64, +64, color, empties, discdiff, 1 );
}
}
//終盤の「速さ優先」探索を行う。
private function fastestFirstEndSolve( ban:AiBoard, bestmove:Array, alpha:int, beta:int, color:int, empties:int, discdiff:int, prevmove:int ):int {
var i:int, j:int;
var score:int = -INFINITY;
var oppcol:int = -color;
var sqnum:int = 0, ev:int;
var flipped:int;
var moves:int = 0;
var best_value:int, best_index:int;
var square:Array = [0];
var goodness:Array = new Array(64);
var board:Array = ban.board;
var em:EmptyList, old_em:EmptyList;
var move_ptr:Array = new Array(64);
for ( old_em = ban.emHead, em = old_em.succ; em != null; old_em = em, em = em.succ ) {
sqnum = em.square;
flipped = ban.doFlips( sqnum, color );
if ( flipped > 0) {
board[sqnum] = color;
old_em.succ = em.succ;
goodness[moves] = fastEval( ban, oppcol );
ban.undoFlips( flipped, oppcol );
board[sqnum] = EMPTY;
old_em.succ = em;
move_ptr[moves] = em;
moves++;
}
}
if ( moves != 0 ) {
for ( i = 0; i < moves; i++ ) {
best_value = goodness[i];
best_index = i;
for ( j = i + 1; j < moves; j++ ) {
if ( goodness[j] > best_value ) {
best_value = goodness[j];
best_index = j;
}
}
em = move_ptr[best_index];
move_ptr[best_index] = move_ptr[i];
goodness[best_index] = goodness[i];
sqnum = em.square;
flipped = ban.doFlips( sqnum, color );
board[sqnum] = color;
em.pred.succ = em.succ;
if ( em.succ != null )
em.succ.pred = em.pred;
if ( empties < FASTESTFIRST ) {
ev = -alphaBetaEndSolve( ban, square, -beta, -alpha, oppcol, empties-1, -discdiff-(flipped*2)-1, 1);
}
else {
ev = -fastestFirstEndSolve( ban, square, -beta, -alpha, oppcol, empties-1, -discdiff-(flipped*2)-1, 1 );
}
ban.undoFlips( flipped, oppcol );
board[sqnum] = EMPTY;
em.pred.succ = em;
if ( em.succ != null )
em.succ.pred = em;
if (ev > score) {
score = ev;
bestmove[0] = sqnum;
if (ev > alpha) {
alpha = ev;
if (ev >= beta) {
return score;
}
}
}
}
}
else {
if ( prevmove == 0 ) {
if ((discdiff+empties) == 64) return 64;
if ((discdiff-empties) == -64) return -64;
return discdiff;
}
else {
score = -fastestFirstEndSolve( ban, square, -beta, -alpha, oppcol, empties, -discdiff, 0 );
}
}
return score;
}
//ゲームの木の末端処理。最終的な石差を計算する。
private function alphaBetaEndSolve( ban:AiBoard, bestmove:Array, alpha:int, beta:int, color:int, empties:int, discdiff:int, prevmove:int ):int {
var score:int = -INFINITY;
var oppcol:int = -color;
var sqnum:int,flipped:int,ev:int;
var square:Array = [0];
var board:Array = ban.board;
var em:EmptyList, old_em:EmptyList;
for (old_em = ban.emHead, em = old_em.succ; em != null; old_em = em, em = em.succ) {
sqnum = em.square;
flipped = ban.doFlips( sqnum, color );
if (flipped > 0) {
board[sqnum] = color;
old_em.succ = em.succ;
if (empties == 2) {
var flipped1:int;
flipped1 = ban.countFlips( ban.emHead.succ.square, oppcol);
if (flipped1 > 0) {
ev = discdiff + ((flipped-flipped1)*2);
}
else {
flipped1 = ban.countFlips( ban.emHead.succ.square, color);
ev = discdiff + (flipped*2);
if (flipped1 > 0) {
ev += (flipped1+1)*2;
}
else {
ev++;
if (ev == 63) ev++;
}
}
}
else {
ev = -alphaBetaEndSolve( ban, square, -beta, -alpha, oppcol, empties-1, -discdiff-(flipped*2)-1, 1);
}
ban.undoFlips( flipped, oppcol );
board[sqnum] = EMPTY;
old_em.succ = em;
if (ev > score) {
score = ev;
bestmove[0] = sqnum;
if (ev > alpha) {
alpha = ev;
if (ev >= beta) {
return score;
}
}
}
}
}
if(score == -INFINITY){
if(prevmove == 0){
if ((discdiff+empties) == 64) return 64;
if ((discdiff-empties) == -64) return -64;
return discdiff;
}
else
return -alphaBetaEndSolve( ban, square, -beta, -alpha, oppcol, empties, -discdiff, 0);
}
return score;
}
//速さ優先探索用関数。相手の着手可能手数が少なくなる手に高い評価を与える。(但し、隅周辺の石の配置により微調整)
private function fastEval( ban:AiBoard, oppcol:int ):int {
var square:int;
var mobility:int = 0;
var stability:int = 0;
var color:int = -oppcol;
var board:Array = ban.board;
var em:EmptyList;
//相手が打てる場所の数をカウント
for ( em = ban.emHead.succ; em != null; em = em.succ ) {
square = em.square;
if ( ban.anyFlips( square, oppcol ) ) {
mobility++;
}
}
//以下、隅周辺の石の配置による微調整
if (board[A1] == color) {
stability++;
if (board[B1] == color) {
stability++;
}
if (board[A2] == color){
stability++;
}
}
else if (board[A1] == EMPTY) {
if (board[B2] == color){
stability--;
stability--;
}
}
if (board[A8] == color) {
stability++;
if (board[B8] == color) {
stability++;
}
if (board[A7] == color) {
stability++;
}
}
else if (board[A8] == EMPTY) {
if (board[B7] == color){
stability--;
stability--;
}
}
if (board[H1] == color) {
stability++;
if (board[G1] == color) {
stability++;
}
if (board[H2] == color) {
stability++;
}
}
else if (board[H1] == EMPTY) {
if (board[G2] == color){
stability--;
stability--;
}
}
if (board[H8] == color) {
stability++;
if (board[G8] == color) {
stability++;
}
if (board[H7] == color) {
stability++;
}
}
else if (board[H8] == EMPTY) {
if (board[G7] == color){
stability--;
stability--;
}
}
return stability - ( mobility << 4 );
}
//指定盤面に対する中盤の評価値を返す。
private function midGame( ban:AiBoard, bestmove:Array, color:int, empties:int, discdiff:int, depth:int ):int {
prepareToSolve(ban);
if ( depth > EVALUE_FIRST ) {
//ゲームの木の上位ノード処理
return evalFirstMidGame( ban, bestmove, -INFINITY, +INFINITY, color, empties, discdiff, depth, 1 );
}
else {
//ゲームの木の末端ノード処理
return alphaBetaMidGame( ban, bestmove, -INFINITY, +INFINITY, color, empties, discdiff, depth, 1 );
}
}
//評価値が高いと予想される手を優先的に探索する中盤処理
private function evalFirstMidGame( ban:AiBoard, bestmove:Array, alpha:int, beta:int, color:int, empties:int, discdiff:int, depth:int, prevmove:int ):int {
var i:int, j:int;
var score:int = -INFINITY;
var oppcol:int = -color;
var sqnum:int = 0, ev:int;
var flipped:int;
var moves:int = 0;
var best_value:int, best_index:int;
var square:Array = [0];
var goodness:Array = new Array(64);
var board:Array = ban.board;
var em:EmptyList, old_em:EmptyList;
var move_ptr:Array = new Array(64);
//優先的に探索するための前準備
for ( old_em = ban.emHead, em = old_em.succ; em != null; old_em = em, em = em.succ ) {
sqnum = em.square;
flipped = ban.doFlips( sqnum, color );
if ( flipped > 0) {
board[sqnum] = color;
old_em.succ = em.succ;
goodness[moves] = fastEval( ban, oppcol );
ban.undoFlips( flipped, oppcol );
board[sqnum] = EMPTY;
old_em.succ = em;
move_ptr[moves] = em;
moves++;
}
}
//打てる場所すべての評価値を算出する。
if ( moves != 0 ) {
for ( i = 0; i < moves; i++ ) {
best_value = goodness[i];
best_index = i;
for ( j = i + 1; j < moves; j++ ) {
if ( goodness[j] > best_value ) {
best_value = goodness[j];
best_index = j;
}
}
em = move_ptr[best_index];
move_ptr[best_index] = move_ptr[i];
goodness[best_index] = goodness[i];
sqnum = em.square;
flipped = ban.doFlips( sqnum, color );
board[sqnum] = color;
em.pred.succ = em.succ;
if ( em.succ != null )
em.succ.pred = em.pred;
if ( depth <= EVALUE_FIRST ) {
ev = -alphaBetaMidGame( ban, square, -beta, -alpha, oppcol, empties-1, -discdiff-(flipped*2)-1, depth-1, 1);
}
else {
ev = -evalFirstMidGame( ban, square, -beta, -alpha, oppcol, empties-1, -discdiff-(flipped*2)-1, depth-1, 1 );
}
ban.undoFlips( flipped, oppcol );
board[sqnum] = EMPTY;
em.pred.succ = em;
if ( em.succ != null )
em.succ.pred = em;
if (ev > score) {
score = ev;
bestmove[0] = sqnum;
if (ev > alpha) {
alpha = ev;
if (ev >= beta) {
return score;
}
}
}
}
}
else {
if ( prevmove == 0 ) {
if (discdiff > 0) return +INFINITY;
if (discdiff < 0) return -INFINITY;
return 0;
}
else {
score = -evalFirstMidGame( ban, square, -beta, -alpha, oppcol, empties, -discdiff, depth, 0 );
}
}
return score;
}
//末端の探索と評価関数のコール処理
private function alphaBetaMidGame( ban:AiBoard, bestmove:Array, alpha:int, beta:int, color:int, empties:int, discdiff:int, depth:int, prevmove:int ):int {
if ( depth < 1 ) return evalue.Eval(ban.board, empties, color); //末端のため、評価値を計算して返す。
var score:int = -INFINITY;
var oppcol:int = -color;
var sqnum:int = 0, ev:int;
var flipped:int;
var moves:int = 0;
var square:Array = [0];
var board:Array = ban.board;
var em:EmptyList, old_em:EmptyList;
//打てる場所すべての評価値を算出する。
for (old_em = ban.emHead, em = old_em.succ; em!=null; old_em = em, em = em.succ) {
sqnum = em.square;
flipped = ban.doFlips( sqnum, color );
if (flipped > 0) {
board[sqnum] = color;
old_em.succ = em.succ;
ev = -alphaBetaMidGame( ban, square, -beta, -alpha, oppcol, empties-1, -discdiff-(flipped*2)-1, depth-1, 1);
ban.undoFlips( flipped, oppcol );
board[sqnum] = EMPTY;
old_em.succ = em;
if (ev > score) {
score = ev;
bestmove[0] = sqnum;
if (ev > alpha) {
alpha = ev;
if (ev >= beta) {
return score;
}
}
}
}
}
if(score == -INFINITY){
if(prevmove == 0){
if (discdiff > 0) return +INFINITY;
if (discdiff < 0) return -INFINITY;
return 0;
}
else
return -alphaBetaMidGame( ban, square, -beta, -alpha, oppcol, empties, -discdiff, depth, 0);
}
return score;
}
}
//////////////////////////////////////////////////
// 盤面の評価値を算出するクラス
//////////////////////////////////////////////////
class Evaluate extends AiHeader {
//AIデータアレイ
private var Line1:Array;
private var Line2:Array;
private var Line3:Array;
private var Line4:Array;
private var Edge8:Array;
private var Diag8:Array;
private var Diag7:Array;
private var Diag6:Array;
private var Diag5:Array;
private var Diag4:Array;
public function Evaluate() {
init();
}
//機能: 評価値算出用パターンデータの登録。
//戻値: なし。
//備考: 固定値。変動なし。
private function init():void {
Line1 = [
+0,+43,-69,-43,+45,-64,+20,+20,-66,-13,-3,-65,-37,+32,-69,
+28,+14,-43,+2,+29,-3,-55,+48,-58,+26,+44,-58,-16,+29,-75,
-47,+20,-59,+2,+10,-68,-22,-29,-56,-23,+39,-59,+10,+9,-14,
+2,+24,-39,-48,+5,-49,+32,+40,-45,+0,+25,-54,-34,+14,-3,
+0,-3,-42,-18,-11,-69,-48,+8,-49,+25,+55,-15,-1,+46,-42,
-28,+49,-47,+25,+50,-58,-16,+19,-63,-31,+39,-80,+8,-27,-75,
-32,-9,-60,-57,+18,-63,+5,+16,-21,-4,+16,-3,-73,+11,-57,
+16,+16,-55,-29,+21,-82,-65,-27,-65,-9,+11,-58,-12,-1,-59,
-20,+22,-57,+17,-16,-33,-4,+16,-51,-55,+21,-24,+20,+25,-42,
+4,+13,-38,-24,+40,-31,+14,-3,-42,-23,-26,-36,-45,+8,-41,
+45,+54,-2,+21,+36,-18,-33,+54,-59,+15,+20,-50,-2,+27,-58,
-43,+33,-59,+24,+9,-59,-7,-7,-58,-25,+37,-3,+0,-3,+0,
+0,+0,-3,-7,-3,-45,+7,+33,-40,-18,+1,-28,-38,+15,-25,
+20,-3,-31,-23,-29,-9,-44,+26,-33,+25,+38,+7,+7,+54,-5,
-13,+52,-26,+25,+64,-48,+1,+40,-30,-18,+20,-27,+20,+2,-53,
-7,+21,-44,-26,+47,-51,+18,+37,-10,+0,+41,-27,-43,+37,-56,
+28,+21,-55,-13,+20,-70,-53,+6,-58,+25,-6,-57,-12,-19,-56,
-22,+35,-59,-14,-24,-55,-21,-12,-5,-83,+47,-64,+21,+11,-63,
-32,+0,-68,-52,+52,-64,-2,-46,-71,-43,-61,-69,-28,+6,-62,
+28,-7,-32,+0,+20,-56,-47,+3,-30,+43,+31,-56,-2,+17,-51,
-27,+3,-3,+0,-3,-47,-23,-22,-24,-43,-2,-65,+18,+34,-30,
-7,+23,-53,-30,+35,-41,+22,+18,-57,-22,-8,-65,-30,+30,-75,
+10,-29,-85,-43,-43,-85,-57,+3,-67,+10,+11,-45,+4,+25,-3,
-64,+18,-42,+18,+44,-51,-12,+32,-57,-45,-4,-50,+17,+18,-46,
-6,+0,-47,-12,+33,-63,-8,-16,-55,-17,-21,-75,-54,-44,-65,
+4,-18,-30,+9,-23,-27,-29,+5,-65,-13,-3,-85,-55,-36,-72,
-66,+31,+1,+6,+15,+8,+2,+28,-36,-9,+68,-74,-3,+7,-27,
-2,+4,-14,-60,-9,-91,-6,-25,-68,-13,-4,-76,-5,+14,-97,
-3,-33,-43,-20,+7,-3,-7,-3,-16,-13,-101,-38,-48,-42,-86,
-80,-96,-43,+0,-36,-53,-47,-61,-56,-62,-3,-72,-11,+1,-57,
-10,+33,+5,-9,+4,-95,+76,+102,-40,-8,-12,-90,-43,+65,+21,
-15,+1,+7,-33,+18,-14,-54,+32,-64,+8,-33,-56,-25,+1,-89,
-75,+3,-96,-6,+75,-70,-20,-17,-92,-41,+15,-75,+0,-79,-88,
-43,+21,-71,-35,+47,-25,+25,-33,-2,-24,-56,-3,+71,-68,-66,
+5,+38,-29,-28,-3,-41,-85,-68,-81,+6,-18,-45,-30,-3,-69,
-18,+22,-3,+0,-3,+0,+0,+0,-3,-7,-3,+1,+1,+1,+0,
+0,+0,-3,-1,-1,-3,+0,-3,-7,-7,-7,-3,-7,-3,-47,
-1,+16,-54,-20,-9,-101,+71,-101,-11,-40,-3,-23,-55,+4,-107,
-85,+89,-8,+15,-8,-105,-83,-35,-8,+88,+89,-91,-19,-36,-40,
-14,+58,-3,-7,-3,-103,-14,+11,-38,-73,-39,-105,-105,-8,-101,
+13,-3,-82,-64,-38,+2,-48,+9,-41,+9,+11,-43,-18,+31,-61,
-29,+36,-76,+10,+10,-58,-16,-9,-38,-25,+12,-75,+14,+2,-48,
-24,+7,-36,-14,+58,-54,+23,+0,-40,-21,+18,-32,-43,+66,-56,
-4,+38,-47,-26,+21,-81,-54,+16,-63,-5,-9,-59,-18,-18,-40,
-14,+23,-47,+47,-48,-34,-7,-19,+2,-1,+2,-32,+0,-42,-60,
-34,+3,-85,-49,+15,-23,+13,-50,-21,-27,-16,-29,-7,+45,-73,
+10,+17,+14,-22,+42,-35,-60,+12,-70,+64,+22,-48,-25,-20,-85,
-54,+2,-34,+40,+2,-72,-43,-13,-41,-51,+24,-31,+13,-34,-60,
-28,+2,-63,-41,+10,-54,+0,+32,-54,-43,-15,-73,-47,-17,-88,
+6,-61,-86,-53,-39,-71,-68,+27,-86,+18,-37,-64,-15,-18,-5,
-85,-102,-44,+4,+22,-58,-31,+19,-103,-58,+21,-73,+3,-42,-65,
-30,-13,-70,-17,+21,-67,+10,-61,-29,-43,-25,-65,-80,-5,+42,
+0,+0,-49,-32,+0,-102,-49,-100,-5,-1,-5,-105,-38,-14,-102,
-73,-102,-89,-3,-18,-84,-25,+0,-78,-85,-12,-12,-64,+74,-70,
-47,-27,-85,-58,+93,-97,-76,-103,-35,-52,-80,-71,-103,-54,-46,
+13,-30,-92,-20,+11,-5,-105,+93,-49,-10,+35,-48,-65,+25,-105,
-6,-6,-56,-4,-21,-72,-45,-56,-75,-32,-2,-64,+12,-30,-70,
-10,-14,-43,-66,-33,+34,-13,+6,-49,-5,+27,-101,-14,+19,-28,
+19,-3,-96,-45,-44,-58,-63,-24,-52,+27,-33,-15,+14,+7,-11,
-54,-14,-47,-18,+19,-18,-28,-26,-84,-51,+8,-78,-25,-46,-85,
-26,-35,-34,-38,+11,-3,+0,-3,+0,+0,+0,-3,-7,-3,-54,
-47,+94,-83,-48,+54,+3,-73,+89,-70,+3,-3,-50,-43,-7,-30,
-67,-29,-26,+16,+26,-30,-18,+9,+1,-5,+51,-29,+3,+44,-77,
-25,-8,-30,-14,+21,-76,+1,+1,-97,-25,-18,-29,-38,-10,-81,
+0,+32,-5,-18,+33,+38,-35,+85,-81,-13,-69,-73,-37,+20,-103,
-68,+21,-63,-8,-7,-58,-22,-50,-36,-8,+39,-44,-27,-66,-28,
-45,-61,-6,+88,-6,-100,-23,+19,-84,-57,-20,-105,-103,-6,-103,
-6,-65,+17,-57,-89,-46,-31,-18,-72,+0,-48,-65,-28,-25,-66,
-62,-63,-43,-10,+27,-52,-10,-37,-51,-7,+15,-3,+0,-3,-65,
-44,-76,-77,-67,+1,-37,-16,+8,-28,-25,+8,-29,-18,+45,-44,
-10,+28,-43,-23,-12,-62,-17,+42,-52,+11,+7,-61,-28,-28,-96,
-31,+40,-63,-12,-36,-40,-17,-11,-3,-48,-58,-57,-9,+0,-45,
-20,+29,-65,-32,-6,-55,+8,-39,-35,-12,-29,-44,+0,+31,-27,
+44,+15,+38,+47,+45,-32,-16,+23,+10,+75,+94,+31,+59,+42,+10,
+11,+61,-75,-2,+0,-40,-16,-13,-32,-30,+10,+35,+46,+44,+11,
+69,+88,+55,+1,+72,+51,+70,+99,+47,+56,+67,+3,+17,+28,+7,
+69,-18,+42,+38,+32,+18,+26,+74,-10,+30,-4,-13,+9,+47,+0,
-3,+0,-23,+29,+92,-26,+9,+53,-19,-61,-97,+41,+56,+18,-37,
-7,+22,+0,-48,+43,+38,+96,+44,+103,+85,+103,+46,+15,+96,+6,
+71,+105,+53,+60,+58,+1,+0,+101,+5,+8,+5,+99,+54,+65,+75,
-33,+78,-36,+36,+104,+47,+56,+96,+45,-33,+69,-93,+71,-91,+9,
+65,+52,-24,-34,+2,+0,+71,+32,-36,+37,+79,+0,+32,+78,-61,
+34,+97,+3,+58,+101,+0,+16,+65,-11,+40,+103,+10,+55,+32,-99,
-18,+33,+97,+76,+97,-15,+34,+67,-18,+8,+85,-31,+77,-4,+14,
+24,+33,+0,-33,+53,+102,+102,+102,+8,+69,+86,+52,-48,+99,+0,
+3,+0,-3,-3,-3,+0,-3,+0,-2,+29,+97,+51,+44,+85,+86,
-33,+97,+44,+41,-13,-14,+14,+35,-30,-37,+93,+44,+14,+37,-61,
-24,-32,-75,-66,+66,+15,+58,+65,+19,+36,+59,+0,-36,+32,-11,
+36,+50,+34,+16,+69,-75,-30,+76,+37,+72,+95,-57,+11,+12,+32,
-36,+57,-6,+65,+94,+103,+57,+60,+22,-18,+45,+8,+105,+107,+103,
+82,+101,+3,+10,+91,+5,+105,+5,+99,+25,+70,+75,+6,+102,+49,
+105,+105,+103,+68,+103,+105,+102,+105,-26,+103,+78,+86,+75,+85,+99,
+22,+101,+1,+41,+22,+31,+64,+82,+99,+44,+18,+102,-3,+102,+8,
+28,+105,+5,+1,+5,+3,+85,+5,+1,+40,+78,+0,+0,+0,+5,
+86,+5,+50,+31,+80,+19,+27,+86,+12,+62,+99,-14,+65,+79,+78,
+7,+84,+71,+85,+78,+63,+63,+66,+99,+38,+21,-7,+107,+7,+52,
+20,+40,+30,+19,+85,+26,+103,-91,+44,+70,+86,+33,+75,+86,-93,
+73,+104,+46,+69,+86,+0,+32,+55,+97,+92,+27,+9,+21,+66,+24,
-69,+94,+73,+84,-13,+8,+58,+70,+0,-3,+0,+73,+81,-14,+62,
+50,+69,-99,+74,+98,+0,+14,+31,+47,+18,+74,-3,+28,+86,-52,
+51,+92,-38,+51,+62,-97,-101,+49,+24,+102,+5,-49,+54,+70,+0,
-42,+99,+0,+3,+0,+94,+33,+83,-52,+94,+82,+7,+30,+103,+64,
+30,+71,-40,+38,+103,+101,+85,-14,+73,+44,+43,-99,+22,+76,-99,
+90,+96,+33,+11,+33,-1,+19,+65,-42,+101,+50,-94,+38,+101,+0,
+11,+0,-9,+38,+4,+62,+16,+83,-3,+35,-1,+54,+27,+77,+7,
+44,+72,-10,+0,+78,+0,+3,+0,+3,+3,+3,+0,-3,+0,+5,
+5,+5,+3,+3,+3,+0,+2,+2,+0,+3,+0,-3,-3,-3,+0,
-3,+0,+5,+6,+5,+5,+5,+5,+5,+1,+5,+5,+5,+7,+3,
+3,+3,+0,+2,+2,+0,+3,+0,+2,+2,+2,+0,+1,+2,+0,
+3,+0,+3,+3,+3,+0,-3,+0,-2,-2,+0,-3,-3,-3,-5,
-5,-5,+0,+3,+0,-3,-3,-3,+0,-3,+0,-16,+29,-18,+55,
+53,+83,-36,-25,+86,-98,+78,+22,+1,+42,+60,+40,-9,+91,+0,
+101,+0,-23,+9,+12,-86,-46,+97,-54,-38,+32,+21,+27,+95,+0,
-79,+97,-73,+63,+27,-23,+20,+33,-33,-61,+93,+21,+89,+31,-14,
-6,+13,-45,-7,+82,-5,+11,+37,+44,+18,+57,-5,-8,-5,-101,
+32,+96,-88,-27,+56,-105,-103,-6,-102,+36,+93,+23,-29,-41,-55,
+7,-13,+11,+66,+18,+81,+56,+55,+0,-36,+46,+5,+65,+5,+25,
+39,+101,+97,-50,+99,+0,+3,+0,-3,-3,-3,+0,-3,+0,-42,
-1,+97,-35,+5,+75,+36,-18,+78,-82,+35,+31,-71,+10,+42,-78,
-42,+83,+64,-5,+93,-41,-46,+22,-46,-65,+69,-36,+43,+95,-57,
+51,+97,+0,-3,+0,-65,+61,+77,-13,+11,+36,-22,-21,+28,+30,
+75,+0,+0,+18,+3,+32,-39,+60,-40,+35,+45,+20,+46,+82,+0,
-21,+51,+27,+72,+60,+28,+58,+74,-7,+31,+73,-38,+82,+3,-5,
+16,+31,+57,-14,+47,-24,-17,+103,+89,+71,+16,-23,+33,+77,+10,
+65,+79,+43,+68,+85,-47,+42,+99,-35,+45,+83,+35,+54,+80,+15,
+9,+81,+39,+50,+33,-8,+31,+57,+3,+0,+3,+1,+21,+62,+27,
+24,+19,-50,-25,+14,+35,+53,+55,+0,+20,+30,+37,-25,+67,+29,
+61,+88,+7,+85,+16,+41,+28,+37,+69,+35,+103,+58,+75,+87,-33,
+18,+91,+102,+105,+5,+52,+36,+49,+61,+7,+76,-33,+58,+96,+40,
+57,+70,+14,+1,+31,+51,+86,+86,-2,+66,+54,-9,+2,+5,-2,
+88,+95,+0,+41,+56,+36,+33,+78,-7,+85,+85,+34,+59,+78,-2,
-9,+18,-22,+59,+71,-18,+46,+68,-31,+0,+33,+14,+68,+75,-35,
+23,+18,-42,+8,+82,-2,+65,+47,+70,+47,+57,+3,+7,+31,+8,
+105,+105,+7,+42,+48,-94,-19,+103,+3,+7,+3,+0,+0,+0,+3,
+0,+3,-24,+97,+101,+39,+53,+78,+23,-56,+3,+72,+72,+70,-20,
+29,+43,-52,-18,+57,+47,-7,+57,-52,-12,+15,-99,-61,+96,+15,
+96,+59,+46,+42,+104,+3,+58,+84,-68,+48,+101,-25,+16,+45,-99,
+11,+41,+21,+85,+97,+5,+25,+45,+40,-11,+71,-37,+45,+42,+37,
+51,+74,+13,-23,+52,+4,+48,+101,+53,+55,+64,-62,-9,+66,-94,
+38,+3,+25,+13,-4,-34,+27,+83,+6,+84,+58,+38,+63,+87,+88,
-12,+81,+1,+58,+66,+18,+58,+72,-62,-20,+45,+3,+29,+60,+18,
+40,+66,-10,-8,+81,-19,+83,+86,-21,+40,+48,+3,+0,+3,-24,
+60,+70,+0,+25,+45,-1,+0,-21,+31,+38,+101,-27,+17,+37,+26,
-37,+72,-20,+43,+67,+58,+57,+85,+71,+4,+82,+18,+70,+85,+26,
+58,+72,-73,+21,+46,+101,+23,+3,+20,+27,+30,+14,-26,+61,-13,
+73,+52,+30,+55,+54,+23,-17,+35,+21,+54,+86,+0,+43,+57,-46,
-15,+49,-11,+70,+33,+2,+20,+22,-9,+20,+47,-36,+18,+35,-15,
+50,+43,-3,+4,+94,-10,+47,+43,-18,+19,+38,-86,-27,+67,-1,
+27,+42,-43,-8,-26,-47,-12,+49,-28,+52,+53,+2,+56,+19,-25,
-42,-4,-38,+49,+78,+0,+45,+45,+49,+3,+51,-3,+0,-3,-7,
+1,+62,-8,+54,+72,-47,+77,+32,+24,+48,+68,-1,-3,+79,+9,
+48,+69,-26,+29,+38,-63,+19,+62,-28,+40,+56,-58,+0,+45,-53,
-20,+71,-63,+49,+69,+10,+42,+45,-3,-39,+94,-49,+58,+83,-53,
+21,+37,-103,+25,+93,-51,+30,+36,-28,+32,+19,-31,+29,+62,-61,
+40,-13,-6,+45,+31,+57,-36,+61,-35,+92,+70,-10,+21,-4,+94,
+7,-15,-101,+40,-3,-46,-26,-3,-19,-44,+23,+20,+28,+65,+19,
+55,+49,-44,+18,+99,+43,+64,+40,+15,+43,+30,-8,-13,+76,-3,
+2,+12,-34,+21,-9,-3,-18,+36,-3,+0,-3,+0,+0,+0,-3,
-7,-3,+92,+34,+83,+21,-11,+62,-8,-14,-8,+66,+43,-3,+8,
-22,+19,+13,-76,+52,-28,+28,+32,+12,+30,+80,+35,-4,+88,+50,
+84,+82,-24,+15,+66,-64,-18,+65,+99,+54,+2,-39,-7,-9,-51,
-35,+71,-12,+5,+79,+0,+10,+56,-21,+21,+92,-55,+60,+66,-30,
-3,+22,-44,-39,+95,-39,+56,+13,-40,-19,-16,-47,-50,+51,-41,
+15,-32,-19,+2,+15,-5,-35,-5,-69,+40,+33,-38,-9,+45,-103,
-80,-4,-84,-8,+22,-89,-43,-52,-11,-28,+55,-55,+65,+22,+0,
+32,+30,-81,-61,+4,+34,+29,+80,-2,+14,+37,+38,-16,+43,-3,
+0,-3,-70,-29,+19,-14,-7,+46,-7,+30,+67,-12,-7,+18,-55,
-3,+98,-43,-14,+74,-58,-29,-26,+14,-13,+93,+60,+57,-41,-7,
-61,-52,-103,-89,+85,-23,+70,+12,+6,+33,+45,-3,-38,+48,-22,
+43,+72,-37,-1,+19,-103,-56,-30,-9,+55,+3,-20,+0,-3,-38,
-29,+54,-49,+55,+23,+9,+50,+51,-30,-44,-36,-11,+56,+45,+51,
+65,+52,-54,+36,+8,-97,+101,+0,-21,+21,+61,-37,-33,+70,+42,
+103,+96,+84,+64,+37,+102,+4,-93,+33,+73,+84,+1,+59,+82,+0,
+12,+41,-58,+81,+86,-14,+52,+88,-97,+51,+99,-61,+70,+53,-66,
+25,+31,+0,-3,+0,-2,+23,+49,-31,+5,-4,-5,-5,-102,+0,
+43,+46,-35,+3,+4,-41,-63,+29,+19,+52,+72,-60,+75,+77,-64,
+68,-93,-91,+97,+105,+28,+80,+81,+99,+66,+28,+5,+8,+5,-47,
+54,+99,-44,-14,+70,-44,+63,+69,+39,+58,+31,-21,+3,+69,-93,
+88,+86,+11,+64,+35,-97,+10,+80,+0,+75,+97,+2,+37,+92,+0,
+85,+63,-36,+78,+97,+3,+59,+3,+0,-101,+0,+73,+63,+103,-3,
+49,+79,-1,-12,+98,+58,+91,+78,+35,+35,+98,-7,+45,+68,+0,
+3,+0,+3,+3,+3,+0,-3,+0,+5,+5,+5,+3,+3,+3,+0,
+2,+2,+0,+3,+0,-3,-3,-3,+0,-3,+0,-80,+76,+65,-99,
+27,+18,+0,-68,+0,+95,+34,+0,-101,+48,+94,+7,-102,+93,-5,
-21,-5,-102,+47,-5,-5,-6,+93,-91,+28,+32,+101,+31,+84,+0,
-3,+0,+95,+75,+0,+94,+11,+94,-5,+93,-5,+97,+65,+0,+38,
+18,+48,+75,-58,+71,-14,+57,+61,+22,+42,+73,+65,+5,+8,+3,
+49,+91,+49,+57,+66,+9,+12,+0,-95,+103,+2,+68,+40,-15,+11,
+19,+99,+31,+100,+101,+69,+64,+91,+101,+65,+28,-15,+44,+21,+10,
+58,+46,-73,+2,+96,-73,+66,+91,+22,+20,+65,+11,+21,+37,-18,
+54,+99,-92,+45,+103,+2,-1,+2,+0,+32,+99,+24,+14,+51,-3,
-100,-100,+2,+16,+99,-1,+3,+43,+23,+15,+27,+9,+44,+28,+43,
+41,+99,+82,-9,+41,-96,+12,+101,-9,+47,+45,-101,+16,+96,-95,
+11,+2,-72,+33,+76,-44,+8,+59,+22,+81,+2,+55,+56,+5,+73,
+15,+80,+0,+54,+55,-21,+45,+49,+93,-17,+95,+93,+96,+93,-51,
+6,+95,+93,+21,+46,+31,+47,+93,-43,+59,+57,-5,+89,+93,+15,
+56,+76,-1,+39,+62,+26,+93,+93,-33,+74,+83,-10,+30,+93,-51,
+42,+61,-79,+43,-97,-34,+30,+14,-5,-96,-102,+0,-42,+0,+38,
+49,-21,-24,+15,-100,-5,-1,-5,-8,+15,-8,-102,+89,+93,-34,
+29,+33,-50,+26,+33,+98,-68,+98,+96,+70,+98,-18,+20,+67,-71,
+21,+93,+91,+95,-6,-69,+52,-4,-6,-6,+93,+93,-34,+76,+35,
+24,+41,-5,-8,-5,-3,+76,-1,-4,-27,+93,-8,-6,-6,+11,
+65,+28,-27,-4,-30,-10,-6,+79,-4,+63,+10,+23,+67,+47,+36,
+31,+70,-93,+46,+102,+63,+63,+83,+42,+58,+99,+91,+91,+0,-15,
+8,+23,-15,-24,+23,+31,+44,+78,+41,+59,+76,+5,+32,+70,-31,
+86,+85,+36,+69,+61,-73,+24,+59,+36,+25,+97,+7,+47,+71,+61,
-10,+34,+0,+3,+0,+3,+3,+3,+0,-3,+0,+18,+47,+82,+19,
+8,+72,-102,-102,+93,+61,+97,+0,-39,-2,+46,+10,+1,+91,-9,
+37,+74,+7,+65,+81,+42,+14,+99,+34,+89,+18,+47,+49,+81,-7,
+23,+37,+80,+47,+2,+24,+37,+36,+2,+11,+34,+0,+81,+78,+12,
+51,+78,+54,+47,+63,-22,+31,+94,+13,+32,+47,-26,+27,+46,+44,
+64,+82,+33,+35,+51,+36,+39,+86,-31,+52,+66,-20,+41,+96,-5,
+89,+93,-31,+54,+65,-6,+18,+71,-49,-54,+93,-42,-1,+69,+24,
+3,+85,-35,+40,+86,+0,+72,+43,+55,+62,+67,-11,-3,+29,+79,
+67,+86,+28,+59,+72,+52,+45,+27,+0,+3,+0,+2,+26,+52,+31,
-29,+91,+9,+26,+85,+28,+33,+82,+16,+22,+68,-9,+73,+86,+20,
+39,+49,-12,+21,+61,-19,+72,-13,-29,+6,+55,-38,-18,+86,+4,
+64,+57,+61,+57,+71,+0,+9,+71,+14,+41,+78,+37,+22,+62,+6,
-2,+79,+49,+63,+60,+40,+33,+54,+27,+31,+56
];
Line2 = [
+0,-5,-31,-23,+4,-18,+11,-13,-6,-13,-13,-21,-10,+1,-14,
-1,+1,+3,+2,-2,-18,-18,+1,-20,+5,+14,-7,-10,-14,-43,
-18,-4,-18,-3,-4,-13,-16,-21,-27,-19,-8,-12,+1,+3,+5,
+2,+0,-24,-16,+1,-5,+5,+15,+4,+0,-6,-21,-7,-2,-27,
-10,-4,-17,-20,-23,-24,-19,-8,-11,-3,+8,+2,-1,-6,-18,
-28,+2,-12,+3,+16,-4,-10,-17,-45,-30,-19,-23,-3,-11,-13,
-18,-22,-37,-24,-11,-15,-5,-5,+3,+0,-3,-17,-18,-1,-21,
-15,-5,-11,-16,-22,-41,-30,-16,-17,-5,-6,-14,-18,-22,-26,
-17,-9,-11,+0,-5,+7,+2,+0,-16,-17,-3,-1,+5,+24,+7,
+0,-4,-14,-10,+0,-18,-6,-12,-18,-21,-23,-21,-21,-15,+2,
+11,+14,+13,+7,+3,-8,-5,+4,+8,+10,+30,+5,-2,-4,-26,
-26,-9,-12,+11,-6,-9,-10,-13,-12,-11,-1,-9,-4,-6,+3,
+0,-6,-7,-18,-2,-14,-14,+2,-14,-20,-22,-37,-25,-8,-18,
-5,-10,-17,-20,-24,-17,-20,-12,-6,+4,+12,+6,+6,+3,-16,
-9,-2,-1,-8,+17,+7,+1,-6,-21,-20,-1,-13,+2,+0,-7,
-10,-12,-15,-14,+0,-15,-3,+12,+2,+0,-8,-9,-17,+3,-12,
+1,+27,-8,-13,-16,-44,-35,-14,-24,-4,-19,-16,-23,-24,-39,
-22,-10,-22,-7,-9,-6,-7,-13,-33,-25,-6,-18,-10,-9,-15,
-18,-25,-52,-40,-23,-18,-8,-6,-23,-22,-26,-33,-27,-19,-11,
-3,-8,+3,+0,-2,-18,-19,-5,-8,-5,+13,+1,-2,-6,-18,
-14,-12,-21,-7,-8,-16,-20,-25,-18,-21,-11,-20,-7,-6,-5,
-6,-14,-17,-25,-9,-15,+1,+6,-12,-16,-21,-47,-40,-32,-28,
-10,-30,-21,-22,-28,-36,-28,-20,-11,-2,-7,+0,-2,-5,-16,
-16,-3,-17,-13,+0,-12,-18,-24,-40,-26,-20,-14,-5,-8,-13,
-16,-22,-23,-17,-9,-10,+4,+1,+6,+5,+3,-8,-14,+5,+4,
+18,+11,+6,+5,-1,-13,-8,+3,-15,+3,+0,-14,-17,-14,-11,
-18,-4,+4,+14,+17,+13,+8,+14,-4,-9,-8,-5,+9,+30,+0,
+3,-1,-29,-26,-8,-10,+5,+7,+4,-9,-13,-5,-25,+3,-10,
+7,+6,+8,+5,+6,-8,-14,+2,-11,+4,+4,-13,-16,-29,-35,
-25,-3,-18,+0,+2,-18,-19,-20,-13,-19,-5,+5,+13,+22,+13,
+10,+12,-18,-9,-2,+10,+18,+34,+12,+3,+15,-34,+6,-4,+1,
+11,+32,-5,-5,-5,-22,-2,+13,+13,+32,+8,+11,+4,+5,+8,
+8,+1,-3,+9,+41,+0,-11,-6,-42,-15,-11,+4,+0,+22,-9,
-17,-16,-33,-31,+9,-22,-17,+14,-3,-11,-26,-3,-25,-5,-29,
+10,+24,-3,-28,-17,-36,-20,-27,-11,-5,-21,-26,-25,-16,-23,
-24,-13,-9,+2,+3,+9,+7,+5,-14,-14,+4,-7,+20,+19,+15,
+10,+0,-15,+0,-17,-11,+0,-1,-14,-18,-15,-8,-17,-5,+1,
+6,+21,+5,-2,-6,+16,-25,+12,-14,+18,+12,-11,-18,-24,-45,
-37,-39,-25,-11,-19,-17,-25,-37,-29,-55,-35,-10,+9,+0,+1,
+6,+0,-15,-20,+2,-8,+2,+9,-9,-18,-20,-38,-22,-26,-19,
-3,-8,-18,-16,-19,-15,-20,-10,-10,+0,+3,+10,+13,+8,-16,
-8,+2,+23,+5,+39,+21,+15,-4,+23,-13,+20,-19,-2,-15,-16,
-10,-14,-12,-20,-10,-4,+5,+35,+4,+10,+20,-31,+6,+19,+5,
-17,+28,+5,-5,-11,-9,-5,-18,+0,-10,+31,-12,-20,-32,-37,
+4,+15,-1,+23,+5,+9,+14,+20,-11,+0,+0,+0,+0,-15,-3,
-7,-15,-29,-26,+23,-14,-4,+16,-14,-14,-25,-11,-24,+0,-8,
+18,+26,+3,-1,+9,-13,-26,+12,+5,+25,+45,+14,-3,-2,-15,
-5,+0,-9,-18,+40,-15,-26,-15,-34,-27,-1,-23,-9,+16,-3,
-1,-1,+21,-15,-15,-22,+0,+33,-13,-23,-18,-45,-36,+9,-47,
-9,-24,-28,-35,-36,-47,-17,-6,-37,-5,-7,-18,-10,+9,-31,
-37,-20,-28,+17,+30,-23,-30,-28,-54,-46,+1,-45,-9,-33,-38,
-40,-39,-45,-40,-30,-21,-3,-14,-4,+5,+0,-31,-25,-17,-2,
+0,+8,-23,-5,-12,-42,-26,-2,-23,-20,+14,-34,-25,-29,-29,
-42,-10,-43,-11,+15,-17,+8,+8,-41,-20,-19,-22,-25,-25,-15,
-18,-27,-54,-46,-52,-47,-18,+21,-36,-40,-33,-53,-55,+2,-24,
+7,-19,-3,-5,-8,-23,-22,+2,-29,-5,+3,-35,-30,-36,-51,
-43,+8,-26,-18,-13,-21,-26,-31,-35,-33,-21,-13,-1,-8,+2,
+2,+0,-14,-18,-7,-3,-7,+12,+8,+5,-6,-20,-20,-6,-21,
-9,-13,-22,-21,-24,-24,-21,-13,+19,+15,-9,+0,+7,+5,-20,
-2,+5,+6,+5,+26,-5,+1,-10,-45,-27,-13,-10,+17,+10,-19,
-14,-25,-37,-20,-14,-8,+0,-10,+7,+4,-1,-11,-17,-1,-22,
-23,-16,-12,-19,-25,-49,-42,-36,-24,-7,-13,-20,-21,-26,-21,
-25,-14,-6,+12,-7,-1,+7,-6,-21,-25,-13,-19,+11,+15,-14,
+3,-2,-48,+4,-22,-41,-6,+9,-16,-11,-15,-32,-20,+0,-7,
+0,-21,-11,+3,-13,-30,-31,-14,+3,+9,+34,-8,-10,-23,-51,
-17,+5,-22,-32,-54,-22,-22,-23,-44,-15,-21,-37,-15,-11,-13,
-11,-19,-40,-55,+4,-45,-5,+0,-24,-24,-32,-53,-55,-25,-28,
-14,-19,-19,-28,-33,-40,-23,-21,-13,+0,-7,+4,+3,-2,-12,
-19,-5,-14,+3,+0,+2,-1,-9,-19,-24,-11,-19,-2,-8,-17,
-20,-24,-22,-25,-16,-23,-12,-13,-4,-4,-7,-19,-24,+2,-12,
-18,+6,-17,-19,-20,-44,-40,-20,-20,-13,-25,-18,-27,-24,-50,
-23,-23,-10,+1,-7,+1,+0,-4,-18,-20,-10,-14,+0,-17,-17,
-17,-24,-35,-33,-32,-20,-4,-11,-16,-17,-21,-23,-18,-8,+4,
+23,+10,+22,+23,+18,+7,+1,+14,+17,+35,+39,+27,+26,+19,+3,
+3,+16,-1,+15,+8,-1,-5,-2,-6,-8,+5,+21,+40,+45,+35,
+33,+23,+6,+22,+26,+42,+45,+49,+30,+27,+23,+7,+26,+20,+16,
+23,+3,+21,+12,+12,-13,-7,+7,+13,+21,+15,+17,+17,+13,+7,
+3,+17,+1,+11,+16,+5,+3,-1,-5,-14,-22,+0,+13,+4,-2,
-8,-5,+0,-7,+5,+21,+50,+45,+29,+36,+35,+4,+17,+39,+40,
+53,+50,+44,+37,+42,+12,+35,+35,+6,+29,+18,-15,+14,+27,+17,
-9,+7,+24,+44,+29,+27,+39,+45,+14,+8,+14,+20,+47,+34,+25,
+21,+29,+0,+16,+2,-19,+33,+19,+18,+12,+22,+0,-21,+31,+6,
+37,+12,+17,+12,+16,+0,+21,+13,+23,+37,-10,+17,+8,+9,-5,
+15,+25,+10,+5,+4,+4,-6,+0,+13,-13,-1,+8,+22,+15,+24,
+18,+12,+15,+6,+23,+29,+29,+45,+18,+24,+27,+20,+5,+35,-5,
+8,+4,-2,-6,-9,+0,-10,+8,-10,+32,+12,+36,+15,+17,+38,
+14,+11,+10,+34,+38,+1,+1,+9,-14,-7,-47,-23,+22,-31,-9,
-9,-7,-17,-11,-8,+13,+24,+14,+21,+21,+18,+0,+0,+15,+9,
+12,+13,-1,-5,-4,-28,-19,+0,-2,+11,+6,-1,-7,-6,+6,
-7,+4,+24,+35,+39,+43,+40,+38,+19,+11,+22,+59,+51,+24,+49,
+41,+22,+41,+39,+48,+20,+38,+15,+29,+24,+15,+28,+12,+22,+38,
+53,+50,+50,+52,+33,+57,+34,+50,+54,+54,+53,+32,+43,+36,+22,
+45,+43,+16,+36,+30,+13,+17,+24,+5,+15,+27,+14,+49,+45,+22,
+37,+26,+17,+19,-26,+47,+29,+34,+5,+15,+5,+0,+8,-9,+29,
+35,+42,+21,+13,+18,+5,+0,+29,+40,+44,+49,+42,+47,+39,+40,
+30,+37,+42,+54,+53,+47,+45,+45,+43,+28,+45,+52,+45,-5,+27,
+30,+13,+14,+26,+44,+14,+51,+34,+39,+44,+43,+33,+41,+42,+40,
+45,+52,+37,+31,+34,+0,+33,+36,+7,+42,+25,-9,+27,+32,+0,
+34,+29,+7,+45,+38,+13,+26,+28,+38,+12,+23,-6,+9,+22,+31,
+16,-25,-22,-25,-3,+27,+29,+20,+0,+6,+5,-7,+6,+27,+21,
+19,+16,+16,+18,+28,-4,+4,+16,+50,+42,+34,+23,+21,+28,+0,
-15,+40,-24,+15,+38,+20,+2,-17,-20,-16,+2,-21,+48,-10,+26,
+21,+13,+9,+24,+27,+32,+15,+22,+13,+14,+5,-43,+30,-10,-5,
+34,-43,-3,-9,+3,-12,+0,+8,+10,+20,+13,+14,+14,+9,+3,
+9,+15,-25,-23,+4,-10,-5,+6,-41,+3,+2,-1,+13,+24,+0,
+0,-4,-3,-17,+3,+4,+18,+8,+10,+16,+9,+4,+0,+13,+24,
+23,+15,+17,+17,+33,-3,-15,+8,-1,+15,+19,-4,-12,-14,+0,
-13,+7,+24,+40,+18,+34,+33,+34,+31,+32,-13,+12,+31,-5,+22,
+18,+18,-38,+40,+40,+38,+3,+0,+27,+0,-9,+0,+9,-22,+1,
+11,+4,+16,+7,-3,+0,-1,+6,+0,+11,+38,+13,-4,-30,-17,
+14,+26,-7,+8,+6,-10,-8,-5,-7,-8,+0,-23,+19,+3,+15,
+17,+11,-22,+7,+29,+8,+41,+30,+24,+18,+30,-9,+31,+8,+19,
-16,+0,-17,-6,+13,-38,+10,-5,+18,+30,+19,+6,+9,+12,+0,
+22,+19,+19,-21,+25,-8,-13,+14,-33,-24,+11,+9,-8,-14,+20,
-19,-12,-14,-54,-12,-16,+20,-31,+20,+8,-28,-31,-19,+13,-45,
+31,-43,-24,-11,+6,-57,+21,+21,-7,+4,-15,-19,-30,-21,-6,
-25,+1,-3,+12,+4,+15,+18,+3,+0,+2,+8,+24,+31,+42,+24,
+24,+22,+4,+16,+36,-3,+14,+6,-9,-10,-20,-15,-13,-5,+24,
+21,+4,+7,+16,-8,+22,-21,+11,+0,+13,+20,-4,-4,-4,-40,
-33,+5,+12,+18,-15,-3,-6,-6,-4,-19,-33,+5,+14,+6,+7,
+16,+8,-4,-8,+6,+18,+16,+24,+2,-6,-9,-19,-13,+2,-5,
+8,+10,-5,-8,-11,-7,-11,+2,+8,+16,+18,+18,+13,+9,+5,
+3,+8,+15,+21,+38,+21,+14,+16,+0,+8,+12,+0,+18,+9,+1,
+0,-4,+1,+0,+2,+27,+19,+35,+27,+23,+6,+19,+12,+18,+17,
+38,+39,+15,+13,+9,+0,+9,+7,+28,+26,+11,+1,+3,-3,-4,
-6,+6,+7,+20,+12,+14,+17,+11,+10,+5,+15,+8,+14,+28,+5,
+0,-7,-21,+0,-9,+1,+18,+3,+0,-2,-9,+2,-2,+4,+3,
+18,+23,+24,+21,+6,+3,+14,+6,+26,+36,+33,+32,+13,+14,+3,
+20,+24,+17,+17,+34,+12,+3,+2,+9,+5,+18,+9,+22,+45,+26,
+16,+21,-20,+5,+33,+11,+28,+43,+13,+6,+3,+9,-1,+5,+8,
+9,+12,+0,-8,-9,-18,-13,+12,-8,+19,+17,+7,+9,+2,-27,
-6,+5,-16,+12,+13,+0,-6,-10,-13,+8,+7,-6,-4,-8,-1,
-14,-18,-21,-7,-1,+13,+17,+13,+16,+16,+11,+9,+6,+18,-1,
+34,+26,+21,+17,+11,-20,+20,+9,+2,+14,-3,+0,-6,-13,+2,
-1,+0,+21,+16,+16,+12,+7,+2,+17,-26,+5,-19,+15,+28,-10,
-2,-6,-27,+9,-27,+19,+5,-28,-12,-13,-23,+15,-19,-10,+18,
+22,+18,+20,+18,+10,+4,+0,+13,+4,+16,+9,+5,-3,-13,-29,
-8,-7,+5,+14,+8,-1,-5,-12,+1,-4,+5,+7,+17,+19,+18,
+12,+16,-2,-1,+13,+29,+35,+22,+11,+11,+2,+10,-4,+29,+1,
+9,+33,-5,-4,-9,+1,-6,+5,+13,+24,+42,+24,+15,+14,+24,
+15,+26,+9,+23,+45,+11,+7,+6,-31,-2,+14,+4,+3,+30,+0,
-6,-7,-17,-2,+14,+12,+12,+27,+21,+14,+11,-13,+0,+21,+0,
+3,+28,+0,-6,-13,-5,-12,+13,+13,+13,+22,-5,-6,-13,-5,
-9,+6,+13,+17,+23,+16,+12,+9,+4,-1,+19,+1,+15,+36,+6,
+4,+6,-13,-11,+21,+12,+11,+18,+10,-4,-12,-1,-10,+5,+0,
+8,+29,+8,+8,+3,+8,-6,+7,-6,+13,+34,+0,-5,-4,-37,
-18,+7,-23,+0,+14,-13,-16,-12,-25,-23,-1,-16,+5,+9,-2,
-5,-6,-22,-24,+2,-24,-5,+5,-11,-17,-22,-32,-27,-1,-9,
+0,-4,-15,-21,-25,-30,-20,-16,-7,-2,-1,+4,-1,-7,-24,
-29,-16,-9,+23,+5,+0,-4,-13,-23,-15,-16,-22,-15,-30,-21,
-22,-30,-18,-25,-5,-10,+14,+9,+9,-7,-10,-24,-17,-11,-24,
-14,-25,-6,-14,-22,-47,-28,-40,-34,-12,+6,-32,-25,-21,-44,
-32,-18,-16,-8,-4,-7,-7,-13,-17,-20,-13,-26,-21,+6,-11,
-22,-23,-49,-36,+1,-22,-6,-9,-21,-24,-28,-27,-24,-21,-8,
-1,-2,+1,+0,-4,-7,-14,-1,-5,+3,+15,+7,-3,-9,-14,
-14,-9,-15,-1,-14,-20,-23,-28,-21,-24,-16,-6,+13,+27,+4,
+6,+2,-20,-5,-4,+14,+18,+13,+2,-3,-12,-13,-15,-9,-12,
+3,+13,-7,-12,-22,-17,-15,-17,-12,-7,-9,+0,-3,-13,-16,
-15,+2,-20,-9,-17,-21,-23,-30,-22,-29,-20,-17,-8,-20,-14,
-25,-30,-17,-24,-16,-13,+4,+12,+9,+5,-3,-7,-13,-6,-23,
+17,+24,-9,-2,-7,-26,-32,-1,-3,-5,-9,-12,-13,-22,-36,
-25,-2,+10,+11,+22,+0,-2,-9,-6,-16,-12,-22,+3,+32,-8,
-13,-12,-39,-36,-5,-27,-11,-12,-26,-24,-32,-27,-23,-18,-29,
+0,-7,-4,-13,-23,-34,-37,-17,-34,-4,+3,-24,-22,-21,-50,
-33,-29,-23,-13,-6,-27,-28,-32,-35,-24,-15,-8,-4,-5,+0,
-3,-9,-15,-20,-7,-12,+4,+18,-4,-5,-13,-16,-25,-10,-15,
-9,-5,-16,-24,-30,-24,-26,-15,-16,+1,+0,-9,-6,-18,-15,
-16,-17,-16,-3,+5,-16,-21,-25,-42,-39,-19,-16,-13,-21,-24,
-26,-32,-29,-33,-22,-6,-2,-6,-1,-7,-12,-10,-19,-2,-12,
-10,-4,-18,-22,-28,-43,-31,-7,-13,-6,-11,-18,-22,-24,-22,
-21,-13,+4,+20,+14,+13,+14,+8,+5,+5,+14,+14,+26,+22,+22,
+17,+13,+1,+2,+11,+0,+19,+13,-5,-3,-1,+2,-7,+11,+23,
+28,+39,+23,+18,+6,+7,-2,+29,+16,+45,+37,+9,+18,+19,-27,
+12,+21,-4,+11,+29,+6,-2,-6,-10,-13,+10,+11,+24,+23,+17,
+18,+18,+7,+4,+18,-15,+14,+16,-13,+1,-16,-29,-17,-6,+0,
+18,+8,-1,-5,-7,+0,-5,+8,+20,+20,+26,+16,+28,+18,-12,
-8,+29,+25,+47,+50,+34,+23,+26,+5,+19,+33,+9,+25,-13,-19,
+4,-4,+23,+5,-11,+28,+22,+14,+27,+24,+33,-9,+1,+10,+17,
+47,+42,+23,+18,+7,-7,-15,+9,+0,-4,+19,-8,+3,-12,+19,
-14,+2,-8,+10,+11,+12,+12,+5,-38,+12,+24,+4,+0,+27,-4,
+2,-11,-16,-19,+2,+4,+10,+11,-28,-9,-17,-16,+2,-7,+6,
+19,+17,+15,+21,+15,+3,+2,+18,+34,+23,-26,+22,+27,+21,+24,
+0,+25,+0,+11,+6,-2,-2,+2,+5,-1,+11,-2,+41,+13,+3,
+13,+5,-19,-5,+24,+36,+9,+23,-12,+1,+2,-52,-20,+18,-9,
-1,+13,-17,-6,-17,-6,+4,-10,+7,+21,+15,+15,+18,+13,+1,
+2,+6,+4,+19,+15,-1,-1,-13,-20,+2,+9,+0,+15,+6,+0,
-3,-2,+1,-10,+7,-4,+14,+16,+12,+17,+12,-18,+3,+11,+27,
+29,+48,+26,+21,+29,+25,+20,+38,-4,+8,+8,-4,+0,-9,-9,
-6,+4,+11,+45,+35,+34,+18,+24,+45,-4,+33,+30,+28,+45,+24,
+20,+21,+6,+0,+27,-4,+29,+8,+16,-1,-1,-23,-22,+28,+7,
+22,+35,+20,+14,+9,+0,-17,+25,+0,+0,+40,+0,-2,-16,-47,
-2,+3,+15,+11,+36,-8,-12,-10,-1,-11,+27,-1,+12,+20,+16,
+15,+7,+0,-8,+21,-17,+22,+43,+24,+12,+14,-32,-18,+27,-36,
+14,+40,+19,-9,-9,-10,-13,+11,-2,-3,+2,+22,+12,+5,-19,
-11,+9,+0,+22,+36,+6,+4,+7,-40,+9,+15,-17,+3,+11,-11,
-14,-5,-20,+5,-2,-8,-6,-47,-14,-8,-27,-12,-39,+18,-30,
-5,-10,-9,-19,-40,-54,-52,+23,-16,+5,+5,-17,-32,-19,-42,
-20,-15,+6,+14,-22,+12,+8,-9,-24,-3,-6,+0,+2,-9,+9,
+5,+13,-50,+23,+3,-34,+7,+26,+1,-8,-20,-29,-36,-11,-7,
+19,+25,+23,+1,+7,-8,-27,+2,+17,-5,-3,-1,-4,-1,-42,
+1,+23,-25,-10,+21,-26,-23,-29,-40,-25,+23,-4,+3,+0,+5,
+1,-7,-24,-26,+9,-27,-23,+2,-29,-16,+1,-59,+8,+10,-14,
-4,+2,-15,-20,-7,-17,-32,-7,-1,+10,+5,+6,+11,+2,-5,
-4,+11,+4,+24,+22,+16,+15,+5,-10,-10,+4,-7,+10,+7,-18,
-15,-16,-13,-13,-5,+20,+37,+7,+29,+22,+18,+16,+13,-11,+8,
+37,+44,+16,+14,+5,-7,-1,+11,+8,+22,-5,+8,+0,-2,-6,
+0,+0,+0,+8,+8,+12,+9,+0,-1,-5,+11,-7,+1,+2,-12,
-8,-5,-14,-10,-11,-11,+10,-5,-7,-11,-15,-13,-16,+2,+5,
+23,+7,+16,+20,+6,-24,+3,+10,+7,+43,+27,+10,+11,+14,+21,
+15,+28,+2,-1,-22,-21,-1,-17,+10,-14,+0,+0,+7,+31,-10,
+15,+12,-18,+9,+2,+2,+23,+29,+0,+1,-1,-14,-6,-2,-28,
-13,-12,-9,-10,-18,-24,-21,+13,-20,-19,-8,+6,-2,-10,-24,
-35,-10,-11,+4,+8,-13,-11,-18,-38,+2,+23,-23,-4,-33,-27,
-20,-22,-21,-23,-16,+0,+13,+5,+8,+11,+4,+3,-5,+8,-6,
+21,+29,+7,+12,+6,-21,+0,+27,-6,+9,+0,-13,-12,-16,-8,
-14,+2,-5,+6,-1,+13,+6,-1,+23,-13,-7,+1,+8,+27,-13,
-8,-16,-40,-30,-15,-20,-5,+1,-3,-19,-15,-21,-21,-16,+1,
+13,+4,+8,+11,+5,-4,-10,+7,+4,+10,+3,-7,-9,-21,-24,
-21,-7,-4,+10,+2,-8,-9,-13,-4,-8,+4
];
Line3 = [
+0,-1,-10,-6,+0,-7,+2,-5,-3,-5,+1,-7,-6,+0,-5,
+1,-3,-3,+0,-2,-10,-11,-7,-4,+0,+0,-3,-4,-2,-8,
-7,-5,-5,+0,-2,-4,-5,-3,-7,-8,-4,-5,+3,-2,+1,
+2,-1,-14,-10,-6,+0,+5,-2,+3,+0,-3,-3,-2,+0,-6,
+2,-1,-13,-9,-8,-11,-10,-6,-5,+1,+6,-3,+0,+0,-6,
-5,-3,-5,+0,-8,-3,-4,-9,-8,-8,-9,-12,-2,-2,-10,
-7,-5,-12,-10,-10,-7,+1,-4,-3,-1,-5,-14,-11,-9,-6,
+1,-3,-12,-6,-9,-8,-10,-12,-6,+0,-5,-5,-5,-7,-9,
-7,-6,-2,+4,-4,+3,+2,+0,-10,-10,-6,+8,+5,+3,+1,
+1,-2,-6,-5,-7,-4,+2,-4,-6,-9,-10,-9,-9,-8,+6,
+8,+4,+4,+3,-4,+1,-6,+0,+3,+9,+2,+3,+0,-2,-7,
-6,-8,-2,+0,-4,-5,-4,-7,-6,-8,-7,-3,+1,-3,+0,
+0,-2,-10,-9,-7,-2,-6,-5,-11,-9,-13,-13,-17,-12,-4,
+1,-2,-8,-10,-9,-8,-11,-8,+2,+4,+2,+1,+3,-1,-1,
-3,-1,+4,+7,+3,-2,+0,-3,-1,-2,+2,+0,+8,+2,+0,
-4,-11,+3,-6,+2,-2,+0,-2,-7,+0,-7,-6,-6,-3,-3,
+1,-2,-8,-5,-3,-18,-10,-12,-4,-2,-19,-11,-9,-10,-17,
-12,-9,-5,-2,-6,-4,-3,-8,-12,-13,-8,-7,-1,-5,-8,
-7,-6,-19,-12,-11,-9,-4,-5,-12,-9,-12,-11,-12,-8,-4,
+1,-5,-3,+0,-4,-13,-12,-8,+1,+3,-2,-3,-2,-3,-5,
-7,-5,-7,-1,-7,-9,-10,-10,-12,-12,-9,-6,+0,-4,-3,
-3,+0,-2,-10,-5,-5,+0,+0,-12,-5,-13,-26,-12,-11,-14,
-7,-2,-11,-9,-3,-14,-11,-12,-6,-1,-6,-2,-2,-7,-14,
-12,-9,-2,-1,+0,-5,-5,-8,-15,-12,-11,-6,-2,-7,-6,
-6,-9,-11,-7,-7,-2,+2,-2,+2,+2,+0,-8,-11,-7,+2,
+2,+4,+3,+0,-7,-1,-4,-4,-3,+0,-1,-9,-10,-10,-10,
-11,-8,+12,+6,+13,+3,+4,+13,-9,-5,-5,+12,+6,+4,+8,
+0,+1,+5,-10,-9,-10,+0,+9,-1,-3,+9,-3,-10,-15,-2,
+0,+1,+3,-1,-2,-10,-12,-7,+5,-10,+2,-11,-10,-15,+1,
-13,-15,-3,+0,+0,-9,-12,-9,-9,-12,-9,+10,+9,+4,+18,
+7,+21,+13,-5,+4,-15,+13,+8,-5,+2,+14,-10,-10,+9,+9,
+1,+8,-5,-6,-1,+1,-10,+10,+10,+4,+18,-6,+2,+3,+9,
-6,+9,-7,+3,+6,+8,-2,+4,-20,-11,+5,+0,+0,-31,-4,
-6,+17,+8,-5,-9,+2,+2,-3,+0,+0,-9,-1,-11,-5,+16,
+0,+10,-1,-5,+3,-12,-12,-1,-5,+0,+2,-7,-10,+0,-10,
-7,-4,-2,+2,-2,+0,+1,-2,-9,-12,-7,+1,+4,-3,+0,
-2,-1,-3,-3,-7,-4,+0,-2,-8,-9,-11,-8,-11,-8,-15,
-4,+5,-7,-8,+6,-24,-11,-18,-3,-5,+2,-13,-11,-10,-7,
-14,-14,-8,-1,+10,-17,-13,-6,-26,-22,-18,-1,+1,+0,+1,
-2,-8,-7,-11,-6,-9,-4,+5,-6,-11,-18,-8,-17,-17,-2,
+0,+0,-10,-12,-18,-7,-12,-7,+4,+3,+5,+6,+1,-6,-1,
-4,+1,+21,+13,-5,+10,-1,+3,+21,+7,+9,+7,+4,+8,-4,
-5,-8,-3,-6,-1,+3,+6,+16,-10,+1,+9,-13,-10,-6,+4,
+8,+9,-5,+0,-7,-5,-5,+27,-1,+0,+11,-6,-2,+0,-15,
-11,-20,+4,+4,+6,+2,+6,+0,-8,-3,+2,+7,+0,+4,-2,
-2,-8,+7,+0,+11,+5,+10,+14,-8,-7,+5,-5,-6,-1,-5,
+1,+0,-19,+0,+1,+1,-10,+2,-8,+0,+14,-9,+0,+8,-14,
-5,+4,+3,+5,+13,+8,-6,-1,+6,-9,+0,+2,+3,+3,-19,
-1,-4,-9,-11,-5,-11,+0,+13,-9,-6,-2,+3,-12,-3,-19,
-3,-28,-9,-10,-21,-27,-16,-7,-6,-3,-21,-5,-9,-15,+7,
-14,-12,-16,-8,+2,-17,-8,-14,-24,-10,-10,-8,-6,-14,-5,
-12,+8,-13,-11,-14,-5,-3,-7,-2,-3,-1,-14,-13,-11,+1,
+0,-1,-1,-5,-19,-13,+0,-10,-8,-4,-6,-19,-17,-17,-16,
-18,-13,-8,-8,-7,-12,-7,-18,-13,-12,-21,-7,+0,+17,-8,
-7,-3,-14,-10,-25,-18,-13,-20,-11,-12,-15,-23,-19,-17,-9,
-6,-10,-2,-5,-9,-17,-17,-14,-10,-13,+0,-7,-10,-13,+3,
-13,-17,-9,-2,-5,-8,-12,-15,-12,-9,-9,-3,+1,-5,+0,
+1,-2,-13,-11,-9,+3,+6,+1,+1,-1,-7,-7,-6,-6,-7,
-1,-8,-11,-9,-12,-12,-12,-11,+7,-1,+0,-5,+2,-9,-2,
-10,-3,-6,+3,+8,+9,-1,-6,-3,-9,-2,-10,-2,-8,+11,
-6,-11,-4,-12,-17,-4,+0,-4,+1,-1,-5,-11,-11,-8,-6,
-4,-10,-17,-10,-17,-17,-18,-26,-5,+0,-3,-13,-12,-13,-12,
-12,-10,-1,+0,+3,+10,+0,+0,-1,-10,-6,-4,+8,-9,+10,
-1,+7,-15,-11,+11,-7,+4,-2,+2,-8,-10,-2,-12,+3,+5,
+0,-1,-2,+0,-14,-11,-5,+5,-21,-3,+4,+7,-6,+3,-31,
-16,-2,-20,-4,-25,-19,-12,-12,-14,-13,-12,-9,+1,-15,-16,
-8,+8,-17,-22,-10,-22,-6,-5,-9,-10,-3,+1,-19,-11,-14,
-6,-2,-17,-11,-10,-20,-13,-11,-4,+0,-6,-1,-1,-6,-13,
-12,-10,-2,+3,-6,-1,-3,-12,-8,-6,-15,-7,-2,-7,-9,
-11,-14,-13,-12,-10,+3,+0,-2,-5,-4,-2,-5,-7,+1,-14,
-1,-7,-5,-8,-10,-19,-11,-18,-10,-9,-5,-11,-12,-17,-14,
-13,-9,-5,-1,-5,-3,-4,-10,-13,-12,-10,-6,-3,-5,-7,
-7,-14,-20,-9,-14,-7,-2,-5,-8,-7,-11,-11,-8,-6,+8,
+11,+10,+14,+11,+11,+0,-2,+3,+14,+12,+17,+17,+9,+10,+1,
+5,+7,+5,+7,+7,-3,-4,-2,-1,-5,+0,+21,+20,+20,+9,
+11,+18,+13,+4,+6,+25,+13,+26,+11,+7,+6,-5,+0,+18,+12,
+10,+9,+5,+2,+5,+4,+3,+4,+8,+12,+7,+13,+8,+8,+4,
-2,+1,+0,+5,+13,+4,-2,-1,-13,-7,-8,+6,+9,+9,-2,
-5,-4,+0,-6,-1,+17,+14,+20,+8,+14,-2,+17,+13,+5,+18,
+23,+22,+14,+12,+10,+11,+16,+5,+3,+26,+9,+1,+4,-22,-1,
+0,-1,+27,+14,+32,+31,+17,+7,+34,+18,+13,+31,+27,+34,+15,
+7,+14,-4,+3,+17,+8,-8,+26,-9,-2,+9,+0,-1,+14,+8,
+4,+2,+21,+6,-4,-7,+5,+9,-11,+15,+33,+5,+6,-3,-18,
-7,-10,+6,+3,+16,+18,-4,-17,-4,-2,-7,+8,+13,+7,+15,
+12,+12,+0,+1,+2,+14,+16,+13,+24,+11,+12,-5,+6,+13,+6,
+8,+6,+5,-3,+1,+0,-4,-1,+14,+2,+2,+6,-3,-24,-27,
-3,-9,-23,-6,+27,+10,-3,+11,-22,-21,+16,+3,-1,+2,-8,
-6,+6,+1,-15,-5,+10,+12,+10,+10,+9,+8,+5,+0,+4,+4,
+3,+18,-8,-4,+2,-7,-10,-12,+8,+10,+10,-4,-6,-4,+1,
-5,+0,+20,+20,+17,+9,+15,+18,+8,+4,+11,-23,-3,+35,+18,
+8,+23,+1,-5,+24,+6,+8,+17,+17,+3,-4,+7,+1,+14,+9,
-1,+22,+27,+19,+32,-21,+8,+33,+4,+24,+4,+31,+8,+4,+23,
+14,+28,-9,+12,+1,+31,+3,+9,+18,-9,+19,+14,+17,+13,-1,
+13,+5,-5,-3,+8,+28,-7,-24,-13,-2,+20,+0,-1,+0,+8,
-1,+16,+17,-2,-12,+13,-6,+7,+21,+19,+26,+21,+26,+11,+22,
+4,+10,+32,+14,+4,+31,+8,+27,+28,+9,+16,+18,+7,+29,+14,
+2,+12,+22,+8,+5,+12,+31,+34,+23,+18,+23,+34,+6,+25,-1,
-3,+33,+4,+10,+12,+0,+13,+29,-27,+20,-5,-13,-2,+16,+4,
+4,+11,+2,+3,+27,+10,+7,+31,-27,+2,+7,-11,+5,-11,+6,
-8,+21,-23,+17,+30,-11,-5,+5,-10,+0,-25,+5,-7,-6,+9,
+8,+13,+0,+5,+2,+4,+2,+1,+13,+13,-24,-15,+3,+12,+0,
+4,-4,+4,+3,+10,-3,-5,+21,+5,-10,-1,-11,+15,+33,+9,
+1,-24,+6,+10,+20,-11,+14,-11,-17,+0,-19,-28,+2,+20,+9,
+10,+27,+2,-5,+30,-11,-5,-1,-3,+7,+18,-18,+6,+10,+0,
+5,+1,+3,-21,-22,-25,-3,+11,-1,+0,-26,+0,+1,+11,-2,
+0,+0,-1,-5,-1,+7,+13,+7,+16,+14,+13,-3,-1,+0,+19,
+17,+17,+13,+14,+13,+0,+8,+11,+3,+7,+5,-4,-4,-7,-5,
-8,-3,+19,+17,+9,-8,+12,+18,-6,+8,+16,+30,-7,+29,+22,
+10,+23,+27,+13,+2,+3,+1,+18,-9,+2,+20,+7,-2,+7,+7,
+11,+6,+11,+10,+9,+0,-2,+1,+6,+8,+10,+1,-1,-10,+5,
-6,-6,+4,+10,+7,-9,-7,-7,-4,-7,-3,+3,+5,+9,-6,
+2,-30,+3,+9,+1,-2,+13,+1,-30,+6,+16,-6,+11,-3,-19,
+24,+18,-12,-4,-3,+27,-8,-25,+10,+11,+26,+25,+6,+17,+0,
-31,+27,+25,+9,-5,+9,-5,+8,-34,-28,+24,+6,-9,-6,-31,
-19,-17,-34,-25,-14,-2,+2,+2,-10,-1,-28,+6,+10,-8,-9,
+13,+27,-12,-2,+11,+21,-20,-16,+0,+9,+7,-32,-2,-32,-13,
-5,-24,+9,+13,+9,+15,+13,+12,+0,+0,+3,+22,+14,+16,+16,
+14,+9,-4,+14,+14,+6,+9,+7,+2,-2,-3,+0,-3,-1,+3,
+1,+16,+15,+1,-2,-3,+2,+3,+12,-1,+5,-4,-2,-6,-22,
-14,+15,-12,-13,+7,-2,-5,+6,-17,-2,-7,+9,+13,+10,+7,
+10,+9,+3,+0,+4,+6,+1,+11,-8,-5,-1,-8,-5,-12,+5,
+8,+9,-4,-7,-6,+0,-5,-1,+9,+8,+11,+11,+6,+8,+4,
+0,+5,+11,+8,+18,+13,+5,+9,+2,-6,+6,+8,+10,+13,+0,
+0,+1,+4,-2,+2,+13,+17,-2,+20,+12,+16,+32,+21,+2,+21,
+5,+11,+24,+4,+13,+10,+1,+19,+15,+7,-30,+6,-1,-23,-18,
+0,-1,+9,+13,+12,+16,+8,+8,+9,-2,+6,+5,+8,+2,+8,
-1,+1,-17,-1,+0,+6,+9,+12,+0,-4,-5,+2,-6,+0,+7,
+11,+18,+16,+11,+16,+2,+13,+6,+7,+11,+32,+15,+10,+25,-2,
+9,+28,+14,+17,+18,+20,-4,+23,+8,-9,+6,+17,+19,+7,+27,
+11,+21,+31,+3,+13,+10,+9,+23,+21,+3,+14,+13,-4,+19,+7,
+4,+17,+0,-7,+3,+9,-14,-8,-2,-11,-24,+28,+5,-7,+9,
+6,-6,+10,+6,-24,-7,+0,+7,-31,-18,+27,-12,+1,-2,-6,
+0,-12,-5,-2,-3,+6,+9,+8,+18,+9,+8,-2,-2,+2,-3,
+19,+5,+10,+13,+21,+3,+0,+20,+3,+8,+9,+0,-2,-4,-5,
-5,+1,+24,-2,-4,+2,+0,-7,+12,-9,-9,-5,-8,+31,-2,
-2,-5,-14,-15,+6,-3,+5,-28,-20,-8,+5,-1,+8,-19,+4,
+11,+8,+10,+6,-4,+4,-8,+2,-4,+4,+10,+7,-5,-13,-17,
-9,-15,+3,+9,+9,+0,-7,-4,+3,-10,-2,+9,+7,+10,+12,
+5,+9,+8,-7,+5,+12,+7,+23,+28,+12,+9,+25,+3,+15,+12,
+6,+13,-7,-2,+0,+8,-7,+5,+6,+9,+10,+11,+8,+25,+12,
+14,+15,+28,+17,+27,+25,+3,+6,-6,+8,+10,+20,+1,+16,+7,
-3,+1,-5,+7,+19,+9,+17,+12,-8,+11,+21,-1,-1,-2,-15,
+2,+12,+0,-3,-17,+13,-19,-20,+8,+11,+9,-8,-3,-8,-4,
-12,-1,+0,+5,+6,-5,+12,+13,+4,+1,+9,-22,+8,+4,-4,
+3,+6,+17,-7,-5,-6,+13,+23,+2,-2,+1,-10,-6,+3,+10,
-7,+14,-12,+8,+14,-9,+4,+22,+6,+9,+12,+0,-1,+6,-4,
-2,+9,+7,-8,+8,-21,-3,+4,-15,+3,-8,-17,-9,+11,-14,
-3,-5,-22,-10,+1,-14,+5,-19,-25,-9,-1,-31,-3,+17,-10,
-8,-6,-24,-13,-11,-11,-10,-10,-3,+1,-1,+1,+3,+1,-16,
-15,-4,-3,+1,+20,+0,-3,-17,+15,-8,+10,+0,+0,-10,-10,
-13,-29,-24,-17,-6,+7,-10,-3,-16,+2,+7,+30,+3,+6,-6,
+9,+21,+4,-2,-1,-31,-14,+17,-13,+5,+11,-15,-6,+10,-14,
-3,-14,-1,-1,+2,-20,-1,-13,-13,-18,-10,-26,-10,+11,-28,
-9,-1,-18,-13,-17,-5,-3,-1,-13,-8,-22,-17,-14,-9,+0,
+3,-2,-1,+2,+1,-7,-10,-8,+5,+2,-4,+20,+3,+0,+18,
-8,-1,-4,-1,-7,-10,-10,-17,-10,-12,-9,+5,+16,-22,-10,
+4,+23,+10,-1,+1,+28,+5,+12,+14,+3,+1,-10,-1,-19,+1,
+0,-3,-28,-11,-13,-21,-10,-2,-4,-1,+1,+0,+0,-4,-11,
-11,-7,-1,-2,+21,+8,-8,-29,+1,-17,-4,-2,-3,-3,-16,
-10,-21,-13,-14,-11,+11,+5,+5,+6,+3,-23,-15,+9,+10,+26,
+12,+9,+16,+3,+1,-9,+0,-2,+2,+7,+20,-2,-7,-13,-6,
-11,+1,+0,+2,+9,+0,+7,+3,-25,+17,+23,+15,+19,+16,+12,
+1,+4,-23,-21,-7,-25,+6,-17,-27,-10,-1,-31,-12,-11,+0,
+5,+6,+10,-4,+5,+8,-6,-8,-4,+10,+30,-11,-5,+10,-27,
-15,-11,-7,-3,+6,-20,-3,-2,-9,-17,-11,-4,+1,-4,+0,
+3,-5,-15,-9,-10,-7,+2,-12,-1,-1,-8,+0,+5,-11,-8,
+0,-7,-18,-9,-21,-15,-13,-12,+9,-10,-17,-6,-1,-12,+6,
+0,-2,+17,+19,-25,+5,-3,-11,-21,+8,+1,-11,-18,-32,-16,
-12,-2,-8,-10,-20,-7,+0,-4,+1,-3,-4,-16,-18,-10,-7,
-6,+0,-12,-7,-22,-9,-15,-25,-8,-2,-6,-11,-9,-14,-14,
-11,-11,+3,+7,+3,+8,+6,+5,-5,-7,-4,+5,+9,+11,+5,
+6,+5,+0,+1,+0,+0,+2,+0,-3,-6,-8,-8,-9,-7,+10,
+14,+5,+7,+9,+6,+0,+4,+3,-1,+8,+10,+10,+5,+9,+11,
+2,-6,-2,+5,+1,+12,-1,+10,-6,-6,-1,+2,+5,+2,+2,
+4,+2,-4,-7,-4,-2,-5,+1,-8,-6,-4,-8,-11,-8,+0,
+3,+3,-6,-8,-10,-6,-10,-6,+7,+10,+6,+11,+14,+2,+12,
-5,+3,+22,+18,+33,+13,+12,+15,-9,-6,+13,+13,+8,+16,+3,
+0,+1,-3,-3,-2,+16,+20,+13,+25,+4,+13,-6,+9,+5,-3,
+19,+25,-7,+7,+22,+27,-5,+7,+0,+0,+27,-7,-3,+23,-8,
+5,+1,+4,+10,-9,-1,+2,-9,-3,-18,-9,+3,+1,+20,-20,
-3,+6,+9,-21,+16,+2,+10,+3,-15,-5,-2,-12,+1,-2,+3,
+7,+1,+8,+7,+6,-6,-7,-4,+10,+8,+8,+0,+6,-2,-4,
+2,+3,+0,+4,+1,-3,-7,-7,-6,-8,-7,+4,+7,+9,-2,
+0,-6,+19,-5,-9,-24,-3,+7,+6,-7,+1,-18,-12,-28,-13,
-9,-8,-14,-8,-8,-3,-10,-2,+4,+7,+4,+4,+4,+2,-3,
-6,-3,-5,-7,+1,-12,-9,-10,-6,-14,-10,+0,+3,+4,-8,
-9,-10,-5,-10,-5,+8,+6,+7,+7,+2,+6,-6,-4,+0,+7,
+10,+24,+26,+6,+15,-3,+9,+20,+5,+9,+11,+4,-7,-1,-4,
-6,+3,-4,+22,+5,+4,+7,+28,+9,+9,+13,+28,+16,+16,+14,
+4,-5,+11,+4,+13,-3,-16,-3,-10,+2,-2,+11,+11,+6,+5,
+6,+13,+1,+2,+20,-6,-7,+3,+0,-7,-4,+15,+0,+10,-28,
-10,-1,+2,-5,+14,-5,-5,-11,+0,-15,-1,+8,+14,+18,-17,
+5,+19,-12,-9,-6,+16,+7,+28,+6,+5,+10,+11,+27,+13,+24,
+3,+2,+5,-8,-19,+23,-2,-5,-9,+21,+17,-15,+3,+19,-25,
+5,+7,+0,+11,+29,-6,+0,+9,+1,-3,+24,+3,+7,+24,-10,
-12,-7,-31,-2,+4,-13,+6,+16,-28,-3,+6,-30,-14,-28,-28,
-4,+20,-28,-9,+17,-4,-25,-2,+1,-12,+15,-21,-11,+1,-25,
-18,-17,-3,+2,-8,+7,-1,+0,-22,-15,-8,+0,-1,+0,+3,
+0,-20,-13,+11,-1,-10,-1,-6,+3,-12,-4,-14,-26,-14,-13,
+4,-10,-26,-4,+27,+2,-1,+16,-16,+8,+30,+22,-5,+17,-32,
-10,-2,-22,+15,-16,-7,-11,-11,-18,-11,-19,-6,-3,-12,-5,
-8,-15,-19,-17,-10,-7,-21,-26,-12,-12,-17,+23,-17,-2,-5,
-2,-12,-11,-11,-25,-14,-14,-12,+1,+5,+0,+7,+6,+2,-9,
-8,-7,+6,+9,+14,+1,+7,+5,+3,-1,+3,-4,+1,-3,-4,
-8,-9,-10,-11,-8,+9,+9,-1,+0,+5,+6,+2,+10,-2,+13,
+6,+5,+17,+5,+3,-2,+0,-5,-4,-2,-25,+2,+2,+1,-8,
+3,-6,+0,+4,-1,+4,+3,+1,-7,-8,-7,-5,-4,-1,-9,
-6,-6,-14,-13,-14,-2,+2,-1,-9,-9,-12,-8,-10,-8,+3,
-3,+4,-9,+6,-1,-3,-15,-1,+13,+8,+19,-7,+5,+19,+11,
-20,+6,-4,+15,+7,-24,-7,-2,-14,-17,-6,+0,-5,+14,+0,
+2,-8,-10,-9,+1,+9,-2,+11,-10,+0,-8,-12,-7,+4,-16,
-10,-14,-17,-9,-11,-27,-12,-9,-9,-7,-5,-5,-6,-19,-19,
-18,-2,+4,-3,-1,-6,-10,-14,-9,-17,-19,-10,-12,-7,-13,
-12,-20,-21,-9,-19,+0,+4,-1,+4,+4,+0,-9,-9,-6,+3,
+5,+7,+3,+5,-1,-9,-1,-1,-3,+2,-3,-6,-8,-11,-8,
-10,-8,-3,+1,-7,-11,-2,-3,-3,-4,-2,-8,+5,-6,+0,
-4,-10,-21,-14,-17,-7,-10,-24,-7,-8,-11,-17,-11,-19,-1,
+3,+0,+0,+2,-2,-7,-7,-5,-8,-4,-1,-9,-6,-9,-20,
-9,-12,-3,+2,-1,-9,-7,-11,-8,-6,-6
];
Line4 = [
+0,-1,-10,-6,+0,-7,+2,-5,-3,-5,+1,-7,-6,+0,-5,
+1,-3,-3,+0,-2,-10,-11,-7,-4,+0,+0,-3,-4,-2,-8,
-7,-5,-5,+0,-2,-4,-5,-3,-7,-8,-4,-5,+3,-2,+1,
+2,-1,-14,-10,-6,+0,+5,-2,+3,+0,-3,-3,-2,+0,-6,
+2,-1,-13,-9,-8,-11,-10,-6,-5,+1,+6,-3,+0,+0,-6,
-5,-3,-5,+0,-8,-3,-4,-9,-8,-8,-9,-12,-2,-2,-10,
-7,-5,-12,-10,-10,-7,+1,-4,-3,-1,-5,-14,-11,-9,-6,
+1,-3,-12,-6,-9,-8,-10,-12,-6,+0,-5,-5,-5,-7,-9,
-7,-6,-2,+4,-4,+3,+2,+0,-10,-10,-6,+8,+5,+3,+1,
+1,-2,-6,-5,-7,-4,+2,-4,-6,-9,-10,-9,-9,-8,+6,
+8,+4,+4,+3,-4,+1,-6,+0,+3,+9,+2,+3,+0,-2,-7,
-6,-8,-2,+0,-4,-5,-4,-7,-6,-8,-7,-3,+1,-3,+0,
+0,-2,-10,-9,-7,-2,-6,-5,-11,-9,-13,-13,-17,-12,-4,
+1,-2,-8,-10,-9,-8,-11,-8,+2,+4,+2,+1,+3,-1,-1,
-3,-1,+4,+7,+3,-2,+0,-3,-1,-2,+2,+0,+8,+2,+0,
-4,-11,+3,-6,+2,-2,+0,-2,-7,+0,-7,-6,-6,-3,-3,
+1,-2,-8,-5,-3,-18,-10,-12,-4,-2,-19,-11,-9,-10,-17,
-12,-9,-5,-2,-6,-4,-3,-8,-12,-13,-8,-7,-1,-5,-8,
-7,-6,-19,-12,-11,-9,-4,-5,-12,-9,-12,-11,-12,-8,-4,
+1,-5,-3,+0,-4,-13,-12,-8,+1,+3,-2,-3,-2,-3,-5,
-7,-5,-7,-1,-7,-9,-10,-10,-12,-12,-9,-6,+0,-4,-3,
-3,+0,-2,-10,-5,-5,+0,+0,-12,-5,-13,-26,-12,-11,-14,
-7,-2,-11,-9,-3,-14,-11,-12,-6,-1,-6,-2,-2,-7,-14,
-12,-9,-2,-1,+0,-5,-5,-8,-15,-12,-11,-6,-2,-7,-6,
-6,-9,-11,-7,-7,-2,+2,-2,+2,+2,+0,-8,-11,-7,+2,
+2,+4,+3,+0,-7,-1,-4,-4,-3,+0,-1,-9,-10,-10,-10,
-11,-8,+12,+6,+13,+3,+4,+13,-9,-5,-5,+12,+6,+4,+8,
+0,+1,+5,-10,-9,-10,+0,+9,-1,-3,+9,-3,-10,-15,-2,
+0,+1,+3,-1,-2,-10,-12,-7,+5,-10,+2,-11,-10,-15,+1,
-13,-15,-3,+0,+0,-9,-12,-9,-9,-12,-9,+10,+9,+4,+18,
+7,+21,+13,-5,+4,-15,+13,+8,-5,+2,+14,-10,-10,+9,+9,
+1,+8,-5,-6,-1,+1,-10,+10,+10,+4,+18,-6,+2,+3,+9,
-6,+9,-7,+3,+6,+8,-2,+4,-20,-11,+5,+0,+0,-31,-4,
-6,+17,+8,-5,-9,+2,+2,-3,+0,+0,-9,-1,-11,-5,+16,
+0,+10,-1,-5,+3,-12,-12,-1,-5,+0,+2,-7,-10,+0,-10,
-7,-4,-2,+2,-2,+0,+1,-2,-9,-12,-7,+1,+4,-3,+0,
-2,-1,-3,-3,-7,-4,+0,-2,-8,-9,-11,-8,-11,-8,-15,
-4,+5,-7,-8,+6,-24,-11,-18,-3,-5,+2,-13,-11,-10,-7,
-14,-14,-8,-1,+10,-17,-13,-6,-26,-22,-18,-1,+1,+0,+1,
-2,-8,-7,-11,-6,-9,-4,+5,-6,-11,-18,-8,-17,-17,-2,
+0,+0,-10,-12,-18,-7,-12,-7,+4,+3,+5,+6,+1,-6,-1,
-4,+1,+21,+13,-5,+10,-1,+3,+21,+7,+9,+7,+4,+8,-4,
-5,-8,-3,-6,-1,+3,+6,+16,-10,+1,+9,-13,-10,-6,+4,
+8,+9,-5,+0,-7,-5,-5,+27,-1,+0,+11,-6,-2,+0,-15,
-11,-20,+4,+4,+6,+2,+6,+0,-8,-3,+2,+7,+0,+4,-2,
-2,-8,+7,+0,+11,+5,+10,+14,-8,-7,+5,-5,-6,-1,-5,
+1,+0,-19,+0,+1,+1,-10,+2,-8,+0,+14,-9,+0,+8,-14,
-5,+4,+3,+5,+13,+8,-6,-1,+6,-9,+0,+2,+3,+3,-19,
-1,-4,-9,-11,-5,-11,+0,+13,-9,-6,-2,+3,-12,-3,-19,
-3,-28,-9,-10,-21,-27,-16,-7,-6,-3,-21,-5,-9,-15,+7,
-14,-12,-16,-8,+2,-17,-8,-14,-24,-10,-10,-8,-6,-14,-5,
-12,+8,-13,-11,-14,-5,-3,-7,-2,-3,-1,-14,-13,-11,+1,
+0,-1,-1,-5,-19,-13,+0,-10,-8,-4,-6,-19,-17,-17,-16,
-18,-13,-8,-8,-7,-12,-7,-18,-13,-12,-21,-7,+0,+17,-8,
-7,-3,-14,-10,-25,-18,-13,-20,-11,-12,-15,-23,-19,-17,-9,
-6,-10,-2,-5,-9,-17,-17,-14,-10,-13,+0,-7,-10,-13,+3,
-13,-17,-9,-2,-5,-8,-12,-15,-12,-9,-9,-3,+1,-5,+0,
+1,-2,-13,-11,-9,+3,+6,+1,+1,-1,-7,-7,-6,-6,-7,
-1,-8,-11,-9,-12,-12,-12,-11,+7,-1,+0,-5,+2,-9,-2,
-10,-3,-6,+3,+8,+9,-1,-6,-3,-9,-2,-10,-2,-8,+11,
-6,-11,-4,-12,-17,-4,+0,-4,+1,-1,-5,-11,-11,-8,-6,
-4,-10,-17,-10,-17,-17,-18,-26,-5,+0,-3,-13,-12,-13,-12,
-12,-10,-1,+0,+3,+10,+0,+0,-1,-10,-6,-4,+8,-9,+10,
-1,+7,-15,-11,+11,-7,+4,-2,+2,-8,-10,-2,-12,+3,+5,
+0,-1,-2,+0,-14,-11,-5,+5,-21,-3,+4,+7,-6,+3,-31,
-16,-2,-20,-4,-25,-19,-12,-12,-14,-13,-12,-9,+1,-15,-16,
-8,+8,-17,-22,-10,-22,-6,-5,-9,-10,-3,+1,-19,-11,-14,
-6,-2,-17,-11,-10,-20,-13,-11,-4,+0,-6,-1,-1,-6,-13,
-12,-10,-2,+3,-6,-1,-3,-12,-8,-6,-15,-7,-2,-7,-9,
-11,-14,-13,-12,-10,+3,+0,-2,-5,-4,-2,-5,-7,+1,-14,
-1,-7,-5,-8,-10,-19,-11,-18,-10,-9,-5,-11,-12,-17,-14,
-13,-9,-5,-1,-5,-3,-4,-10,-13,-12,-10,-6,-3,-5,-7,
-7,-14,-20,-9,-14,-7,-2,-5,-8,-7,-11,-11,-8,-6,+8,
+11,+10,+14,+11,+11,+0,-2,+3,+14,+12,+17,+17,+9,+10,+1,
+5,+7,+5,+7,+7,-3,-4,-2,-1,-5,+0,+21,+20,+20,+9,
+11,+18,+13,+4,+6,+25,+13,+26,+11,+7,+6,-5,+0,+18,+12,
+10,+9,+5,+2,+5,+4,+3,+4,+8,+12,+7,+13,+8,+8,+4,
-2,+1,+0,+5,+13,+4,-2,-1,-13,-7,-8,+6,+9,+9,-2,
-5,-4,+0,-6,-1,+17,+14,+20,+8,+14,-2,+17,+13,+5,+18,
+23,+22,+14,+12,+10,+11,+16,+5,+3,+26,+9,+1,+4,-22,-1,
+0,-1,+27,+14,+32,+31,+17,+7,+34,+18,+13,+31,+27,+34,+15,
+7,+14,-4,+3,+17,+8,-8,+26,-9,-2,+9,+0,-1,+14,+8,
+4,+2,+21,+6,-4,-7,+5,+9,-11,+15,+33,+5,+6,-3,-18,
-7,-10,+6,+3,+16,+18,-4,-17,-4,-2,-7,+8,+13,+7,+15,
+12,+12,+0,+1,+2,+14,+16,+13,+24,+11,+12,-5,+6,+13,+6,
+8,+6,+5,-3,+1,+0,-4,-1,+14,+2,+2,+6,-3,-24,-27,
-3,-9,-23,-6,+27,+10,-3,+11,-22,-21,+16,+3,-1,+2,-8,
-6,+6,+1,-15,-5,+10,+12,+10,+10,+9,+8,+5,+0,+4,+4,
+3,+18,-8,-4,+2,-7,-10,-12,+8,+10,+10,-4,-6,-4,+1,
-5,+0,+20,+20,+17,+9,+15,+18,+8,+4,+11,-23,-3,+35,+18,
+8,+23,+1,-5,+24,+6,+8,+17,+17,+3,-4,+7,+1,+14,+9,
-1,+22,+27,+19,+32,-21,+8,+33,+4,+24,+4,+31,+8,+4,+23,
+14,+28,-9,+12,+1,+31,+3,+9,+18,-9,+19,+14,+17,+13,-1,
+13,+5,-5,-3,+8,+28,-7,-24,-13,-2,+20,+0,-1,+0,+8,
-1,+16,+17,-2,-12,+13,-6,+7,+21,+19,+26,+21,+26,+11,+22,
+4,+10,+32,+14,+4,+31,+8,+27,+28,+9,+16,+18,+7,+29,+14,
+2,+12,+22,+8,+5,+12,+31,+34,+23,+18,+23,+34,+6,+25,-1,
-3,+33,+4,+10,+12,+0,+13,+29,-27,+20,-5,-13,-2,+16,+4,
+4,+11,+2,+3,+27,+10,+7,+31,-27,+2,+7,-11,+5,-11,+6,
-8,+21,-23,+17,+30,-11,-5,+5,-10,+0,-25,+5,-7,-6,+9,
+8,+13,+0,+5,+2,+4,+2,+1,+13,+13,-24,-15,+3,+12,+0,
+4,-4,+4,+3,+10,-3,-5,+21,+5,-10,-1,-11,+15,+33,+9,
+1,-24,+6,+10,+20,-11,+14,-11,-17,+0,-19,-28,+2,+20,+9,
+10,+27,+2,-5,+30,-11,-5,-1,-3,+7,+18,-18,+6,+10,+0,
+5,+1,+3,-21,-22,-25,-3,+11,-1,+0,-26,+0,+1,+11,-2,
+0,+0,-1,-5,-1,+7,+13,+7,+16,+14,+13,-3,-1,+0,+19,
+17,+17,+13,+14,+13,+0,+8,+11,+3,+7,+5,-4,-4,-7,-5,
-8,-3,+19,+17,+9,-8,+12,+18,-6,+8,+16,+30,-7,+29,+22,
+10,+23,+27,+13,+2,+3,+1,+18,-9,+2,+20,+7,-2,+7,+7,
+11,+6,+11,+10,+9,+0,-2,+1,+6,+8,+10,+1,-1,-10,+5,
-6,-6,+4,+10,+7,-9,-7,-7,-4,-7,-3,+3,+5,+9,-6,
+2,-30,+3,+9,+1,-2,+13,+1,-30,+6,+16,-6,+11,-3,-19,
+24,+18,-12,-4,-3,+27,-8,-25,+10,+11,+26,+25,+6,+17,+0,
-31,+27,+25,+9,-5,+9,-5,+8,-34,-28,+24,+6,-9,-6,-31,
-19,-17,-34,-25,-14,-2,+2,+2,-10,-1,-28,+6,+10,-8,-9,
+13,+27,-12,-2,+11,+21,-20,-16,+0,+9,+7,-32,-2,-32,-13,
-5,-24,+9,+13,+9,+15,+13,+12,+0,+0,+3,+22,+14,+16,+16,
+14,+9,-4,+14,+14,+6,+9,+7,+2,-2,-3,+0,-3,-1,+3,
+1,+16,+15,+1,-2,-3,+2,+3,+12,-1,+5,-4,-2,-6,-22,
-14,+15,-12,-13,+7,-2,-5,+6,-17,-2,-7,+9,+13,+10,+7,
+10,+9,+3,+0,+4,+6,+1,+11,-8,-5,-1,-8,-5,-12,+5,
+8,+9,-4,-7,-6,+0,-5,-1,+9,+8,+11,+11,+6,+8,+4,
+0,+5,+11,+8,+18,+13,+5,+9,+2,-6,+6,+8,+10,+13,+0,
+0,+1,+4,-2,+2,+13,+17,-2,+20,+12,+16,+32,+21,+2,+21,
+5,+11,+24,+4,+13,+10,+1,+19,+15,+7,-30,+6,-1,-23,-18,
+0,-1,+9,+13,+12,+16,+8,+8,+9,-2,+6,+5,+8,+2,+8,
-1,+1,-17,-1,+0,+6,+9,+12,+0,-4,-5,+2,-6,+0,+7,
+11,+18,+16,+11,+16,+2,+13,+6,+7,+11,+32,+15,+10,+25,-2,
+9,+28,+14,+17,+18,+20,-4,+23,+8,-9,+6,+17,+19,+7,+27,
+11,+21,+31,+3,+13,+10,+9,+23,+21,+3,+14,+13,-4,+19,+7,
+4,+17,+0,-7,+3,+9,-14,-8,-2,-11,-24,+28,+5,-7,+9,
+6,-6,+10,+6,-24,-7,+0,+7,-31,-18,+27,-12,+1,-2,-6,
+0,-12,-5,-2,-3,+6,+9,+8,+18,+9,+8,-2,-2,+2,-3,
+19,+5,+10,+13,+21,+3,+0,+20,+3,+8,+9,+0,-2,-4,-5,
-5,+1,+24,-2,-4,+2,+0,-7,+12,-9,-9,-5,-8,+31,-2,
-2,-5,-14,-15,+6,-3,+5,-28,-20,-8,+5,-1,+8,-19,+4,
+11,+8,+10,+6,-4,+4,-8,+2,-4,+4,+10,+7,-5,-13,-17,
-9,-15,+3,+9,+9,+0,-7,-4,+3,-10,-2,+9,+7,+10,+12,
+5,+9,+8,-7,+5,+12,+7,+23,+28,+12,+9,+25,+3,+15,+12,
+6,+13,-7,-2,+0,+8,-7,+5,+6,+9,+10,+11,+8,+25,+12,
+14,+15,+28,+17,+27,+25,+3,+6,-6,+8,+10,+20,+1,+16,+7,
-3,+1,-5,+7,+19,+9,+17,+12,-8,+11,+21,-1,-1,-2,-15,
+2,+12,+0,-3,-17,+13,-19,-20,+8,+11,+9,-8,-3,-8,-4,
-12,-1,+0,+5,+6,-5,+12,+13,+4,+1,+9,-22,+8,+4,-4,
+3,+6,+17,-7,-5,-6,+13,+23,+2,-2,+1,-10,-6,+3,+10,
-7,+14,-12,+8,+14,-9,+4,+22,+6,+9,+12,+0,-1,+6,-4,
-2,+9,+7,-8,+8,-21,-3,+4,-15,+3,-8,-17,-9,+11,-14,
-3,-5,-22,-10,+1,-14,+5,-19,-25,-9,-1,-31,-3,+17,-10,
-8,-6,-24,-13,-11,-11,-10,-10,-3,+1,-1,+1,+3,+1,-16,
-15,-4,-3,+1,+20,+0,-3,-17,+15,-8,+10,+0,+0,-10,-10,
-13,-29,-24,-17,-6,+7,-10,-3,-16,+2,+7,+30,+3,+6,-6,
+9,+21,+4,-2,-1,-31,-14,+17,-13,+5,+11,-15,-6,+10,-14,
-3,-14,-1,-1,+2,-20,-1,-13,-13,-18,-10,-26,-10,+11,-28,
-9,-1,-18,-13,-17,-5,-3,-1,-13,-8,-22,-17,-14,-9,+0,
+3,-2,-1,+2,+1,-7,-10,-8,+5,+2,-4,+20,+3,+0,+18,
-8,-1,-4,-1,-7,-10,-10,-17,-10,-12,-9,+5,+16,-22,-10,
+4,+23,+10,-1,+1,+28,+5,+12,+14,+3,+1,-10,-1,-19,+1,
+0,-3,-28,-11,-13,-21,-10,-2,-4,-1,+1,+0,+0,-4,-11,
-11,-7,-1,-2,+21,+8,-8,-29,+1,-17,-4,-2,-3,-3,-16,
-10,-21,-13,-14,-11,+11,+5,+5,+6,+3,-23,-15,+9,+10,+26,
+12,+9,+16,+3,+1,-9,+0,-2,+2,+7,+20,-2,-7,-13,-6,
-11,+1,+0,+2,+9,+0,+7,+3,-25,+17,+23,+15,+19,+16,+12,
+1,+4,-23,-21,-7,-25,+6,-17,-27,-10,-1,-31,-12,-11,+0,
+5,+6,+10,-4,+5,+8,-6,-8,-4,+10,+30,-11,-5,+10,-27,
-15,-11,-7,-3,+6,-20,-3,-2,-9,-17,-11,-4,+1,-4,+0,
+3,-5,-15,-9,-10,-7,+2,-12,-1,-1,-8,+0,+5,-11,-8,
+0,-7,-18,-9,-21,-15,-13,-12,+9,-10,-17,-6,-1,-12,+6,
+0,-2,+17,+19,-25,+5,-3,-11,-21,+8,+1,-11,-18,-32,-16,
-12,-2,-8,-10,-20,-7,+0,-4,+1,-3,-4,-16,-18,-10,-7,
-6,+0,-12,-7,-22,-9,-15,-25,-8,-2,-6,-11,-9,-14,-14,
-11,-11,+3,+7,+3,+8,+6,+5,-5,-7,-4,+5,+9,+11,+5,
+6,+5,+0,+1,+0,+0,+2,+0,-3,-6,-8,-8,-9,-7,+10,
+14,+5,+7,+9,+6,+0,+4,+3,-1,+8,+10,+10,+5,+9,+11,
+2,-6,-2,+5,+1,+12,-1,+10,-6,-6,-1,+2,+5,+2,+2,
+4,+2,-4,-7,-4,-2,-5,+1,-8,-6,-4,-8,-11,-8,+0,
+3,+3,-6,-8,-10,-6,-10,-6,+7,+10,+6,+11,+14,+2,+12,
-5,+3,+22,+18,+33,+13,+12,+15,-9,-6,+13,+13,+8,+16,+3,
+0,+1,-3,-3,-2,+16,+20,+13,+25,+4,+13,-6,+9,+5,-3,
+19,+25,-7,+7,+22,+27,-5,+7,+0,+0,+27,-7,-3,+23,-8,
+5,+1,+4,+10,-9,-1,+2,-9,-3,-18,-9,+3,+1,+20,-20,
-3,+6,+9,-21,+16,+2,+10,+3,-15,-5,-2,-12,+1,-2,+3,
+7,+1,+8,+7,+6,-6,-7,-4,+10,+8,+8,+0,+6,-2,-4,
+2,+3,+0,+4,+1,-3,-7,-7,-6,-8,-7,+4,+7,+9,-2,
+0,-6,+19,-5,-9,-24,-3,+7,+6,-7,+1,-18,-12,-28,-13,
-9,-8,-14,-8,-8,-3,-10,-2,+4,+7,+4,+4,+4,+2,-3,
-6,-3,-5,-7,+1,-12,-9,-10,-6,-14,-10,+0,+3,+4,-8,
-9,-10,-5,-10,-5,+8,+6,+7,+7,+2,+6,-6,-4,+0,+7,
+10,+24,+26,+6,+15,-3,+9,+20,+5,+9,+11,+4,-7,-1,-4,
-6,+3,-4,+22,+5,+4,+7,+28,+9,+9,+13,+28,+16,+16,+14,
+4,-5,+11,+4,+13,-3,-16,-3,-10,+2,-2,+11,+11,+6,+5,
+6,+13,+1,+2,+20,-6,-7,+3,+0,-7,-4,+15,+0,+10,-28,
-10,-1,+2,-5,+14,-5,-5,-11,+0,-15,-1,+8,+14,+18,-17,
+5,+19,-12,-9,-6,+16,+7,+28,+6,+5,+10,+11,+27,+13,+24,
+3,+2,+5,-8,-19,+23,-2,-5,-9,+21,+17,-15,+3,+19,-25,
+5,+7,+0,+11,+29,-6,+0,+9,+1,-3,+24,+3,+7,+24,-10,
-12,-7,-31,-2,+4,-13,+6,+16,-28,-3,+6,-30,-14,-28,-28,
-4,+20,-28,-9,+17,-4,-25,-2,+1,-12,+15,-21,-11,+1,-25,
-18,-17,-3,+2,-8,+7,-1,+0,-22,-15,-8,+0,-1,+0,+3,
+0,-20,-13,+11,-1,-10,-1,-6,+3,-12,-4,-14,-26,-14,-13,
+4,-10,-26,-4,+27,+2,-1,+16,-16,+8,+30,+22,-5,+17,-32,
-10,-2,-22,+15,-16,-7,-11,-11,-18,-11,-19,-6,-3,-12,-5,
-8,-15,-19,-17,-10,-7,-21,-26,-12,-12,-17,+23,-17,-2,-5,
-2,-12,-11,-11,-25,-14,-14,-12,+1,+5,+0,+7,+6,+2,-9,
-8,-7,+6,+9,+14,+1,+7,+5,+3,-1,+3,-4,+1,-3,-4,
-8,-9,-10,-11,-8,+9,+9,-1,+0,+5,+6,+2,+10,-2,+13,
+6,+5,+17,+5,+3,-2,+0,-5,-4,-2,-25,+2,+2,+1,-8,
+3,-6,+0,+4,-1,+4,+3,+1,-7,-8,-7,-5,-4,-1,-9,
-6,-6,-14,-13,-14,-2,+2,-1,-9,-9,-12,-8,-10,-8,+3,
-3,+4,-9,+6,-1,-3,-15,-1,+13,+8,+19,-7,+5,+19,+11,
-20,+6,-4,+15,+7,-24,-7,-2,-14,-17,-6,+0,-5,+14,+0,
+2,-8,-10,-9,+1,+9,-2,+11,-10,+0,-8,-12,-7,+4,-16,
-10,-14,-17,-9,-11,-27,-12,-9,-9,-7,-5,-5,-6,-19,-19,
-18,-2,+4,-3,-1,-6,-10,-14,-9,-17,-19,-10,-12,-7,-13,
-12,-20,-21,-9,-19,+0,+4,-1,+4,+4,+0,-9,-9,-6,+3,
+5,+7,+3,+5,-1,-9,-1,-1,-3,+2,-3,-6,-8,-11,-8,
-10,-8,-3,+1,-7,-11,-2,-3,-3,-4,-2,-8,+5,-6,+0,
-4,-10,-21,-14,-17,-7,-10,-24,-7,-8,-11,-17,-11,-19,-1,
+3,+0,+0,+2,-2,-7,-7,-5,-8,-4,-1,-9,-6,-9,-20,
-9,-12,-3,+2,-1,-9,-7,-11,-8,-6,-6
];
Edge8 = [
+0,-9,-1,-14,-12,-8,-38,-45,-31,-64,-60,-11,-54,-28,+46,
+57,+22,+66,+61,+16,-28,+24,+10,+0,+0,-11,-2,-12,-24,-10,
-21,-24,-7,-17,-42,-15,-30,-27,-26,-49,-40,+25,+51,+25,+39,
+27,+5,+15,+17,+2,+11,+13,+2,+28,+7,-2,+10,+3,-5,-17,
-26,-34,-9,-54,-49,-27,-25,-48,+21,+50,+9,+45,+51,+10,+3,
+28,-8,+10,+10,-4,+16,-2,-15,+0,-11,-15,+1,-32,-3,-20,
-44,-42,-2,-27,-25,+26,+25,+16,+53,+50,+21,+2,-6,-2,+4,
+7,-16,-2,-10,-26,-6,-13,-24,+6,-13,+7,-33,-51,-34,-18,
-35,-32,+11,-21,-1,+40,+0,+21,+19,+27,+7,+8,-4,+18,+14,
+0,+2,+4,+11,-2,-4,-68,-15,-13,+0,-13,+5,-39,-13,+1,
+40,-3,+9,+0,+24,+8,+38,+11,+1,+9,+2,+0,+0,-1,-10,
+3,-10,-5,-1,-1,-31,-6,-5,-21,-34,-18,+4,+54,-4,+42,
+0,+63,-12,-58,-15,-3,-1,-9,-11,+0,-16,-16,-20,-17,-1,
-23,-31,-23,+0,+24,-19,-18,-21,+28,+84,+27,-9,+0,+30,+20,
+13,+5,+30,+0,+12,+18,+0,+5,+7,-4,-7,+33,+0,-61,-18,
-11,-47,-26,-41,-52,+32,+0,+12,+59,+0,+18,+21,+12,+1,+21,
+0,+1,+9,+0,-5,+7,-7,-12,+18,-7,-40,-2,-4,-41,-14,
-48,-34,+42,+0,+26,+49,+0,+22,+24,+34,+5,+4,+0,-17,-16,
+0,-21,+7,-9,-25,-5,-19,-11,-29,+64,-32,-2,-2,-24,+7,
+10,+11,+33,+69,+33,-19,+29,-7,+24,+9,+15,+20,+15,+12,+0,
+7,-3,+4,-69,+13,+12,-63,-24,-18,-65,-18,+13,+43,+17,+22,
+26,+31,-2,+16,-8,+16,+18,+14,+4,+15,-2,-8,-7,-9,+2,
-18,+12,-27,-32,-18,-28,-20,-16,+7,+15,+13,+19,+51,+13,+23,
-18,+6,+2,+31,+0,+0,+5,-17,-18,-18,-17,-1,-17,+16,-33,
+6,-35,-13,-42,-20,-7,-48,-27,+0,+0,+0,-6,+0,+0,-10,
+4,-52,+0,+0,+0,-42,-84,-54,-56,-64,+47,-84,+0,+0,-48,
-28,-66,+12,-76,-20,+0,+0,+0,-22,-56,+20,-14,-25,-36,+0,
+0,+0,-20,-74,-14,-21,-19,-58,-62,-56,+0,+1,-70,-21,+3,
-38,+18,+0,+0,+0,-17,+0,-6,-25,-33,-49,+0,+0,+0,-29,
-84,-30,-35,-77,-68,-62,+0,-84,-15,-84,-20,+10,+66,+28,+84,
+0,+0,-84,-84,-84,-4,-3,-23,+0,+0,+0,-32,-72,-75,-18,
-84,-84,-84,-84,-84,-44,-69,-76,+24,+28,-9,+0,+84,+0,+5,
-38,-22,-18,-32,-31,+0,+0,+0,-28,-21,-15,-31,-13,-61,-15,
+27,+9,-10,-15,-21,+28,+84,+0,+0,+0,+0,-84,-42,+84,-22,
-70,-50,+0,+0,+0,-23,-15,-47,-28,+46,-84,+51,+0,+0,-16,
+37,-63,-13,+0,-56,+84,+0,+0,+84,+0,-84,-24,+0,-1,+0,
+0,+0,-58,+0,-66,-84,+0,-84,+0,+0,+0,-40,+0,-32,+17,
+0,-16,-84,+0,+0,-28,+0,-84,-13,-42,-10,+0,+0,+0,-47,
+0,-63,-13,-84,-22,+0,+0,+0,-1,+0,-18,-18,+0,-54,+0,
+0,+0,-84,+0,+84,-43,+13,-37,+0,+0,+0,-84,+0,+0,-75,
+0,-36,-84,+0,+0,-84,+0,-52,+43,+51,+16,+0,+0,+0,+49,
+67,+12,+8,-17,-16,+0,+0,+0,+4,-7,-8,-42,-84,-53,+44,
+84,-84,-21,-25,-54,+13,+42,+23,+0,+0,+0,+21,-32,+10,-3,
-56,-3,+0,+0,+0,-9,-30,-9,+12,-18,+8,+16,+60,-63,+7,
-40,-21,+41,+7,+54,+0,+0,+0,+61,+84,+5,-14,-5,+3,+0,
+0,+0,-15,-70,-35,-6,-84,-32,-20,+0,+0,-26,-62,-63,+30,
+58,+59,+0,+0,+0,+45,+43,-17,+0,+0,+0,+0,+0,+0,+4,
-3,-13,+63,+56,+84,+28,-57,-28,-12,-62,-57,+4,+0,+31,+0,
+0,+0,+48,+24,-10,+0,+0,+0,+0,+0,+0,-28,-49,-22,-58,
-59,-59,-78,-68,-55,-22,-52,-24,+44,+0,+84,+0,+0,+0,+73,
+58,+63,+0,+0,+0,+0,+0,+0,-28,-56,-45,-49,+47,+23,+63,
+68,+2,-33,-44,-55,+61,+0,+29,+0,+0,+0,+40,+56,+36,+0,
+0,+0,+0,+0,+0,+1,+18,-26,-71,+0,-84,+84,+0,+36,-14,
-52,-62,+47,+0,+37,+0,+0,+0,+56,+28,+16,+0,+0,+0,+0,
+0,+0,-20,-49,-21,-84,+0,-84,+0,-84,-80,+11,-47,-34,-74,
+0,+0,+0,+0,+0,+58,+0,+33,+0,+0,+0,+0,+0,+0,-43,
-26,-37,+0,+0,-84,-84,+67,-84,-45,-84,-74,+22,+0,+84,+0,
+0,+0,+0,-84,+0,-7,+0,-29,+0,+0,+0,-56,-84,-59,-49,
+0,+84,+0,+0,+0,-60,-84,-53,+6,+0,-21,+0,+0,+0,-12,
-84,+1,-5,+0,-10,+0,+0,+0,-26,-43,-31,-8,-74,+9,+28,
+0,+0,-7,-49,-1,+22,+0,+0,+0,+0,+0,-34,+0,-84,-25,
+0,-43,+0,+0,+0,-27,-4,-31,-24,-28,-68,-14,+0,-60,-19,
-84,-21,+38,+0,+84,+0,+0,+0,+64,+0,+15,+0,+0,+0,+0,
+0,+0,-3,+0,-12,-45,+0,-84,+0,+0,-79,-6,-59,-41,+36,
+0,+41,+0,+0,+0,+36,+0,+6,+0,+0,+0,+0,+0,+0,-1,
+0,-18,+29,+0,+12,+28,+0,-10,+6,+11,-25,+57,+0,+0,+0,
+0,+0,+80,+0,+22,+0,+0,+0,+0,+0,+0,+1,+0,-30,-44,
+0,+0,+42,+0,-28,+1,-39,-43,+38,-47,+32,+34,+0,+64,+55,
-8,+41,+8,+33,-4,+17,-25,-24,+2,-9,+1,-36,-84,-48,-63,
-84,-45,-41,-14,-41,+16,+18,+13,+24,+0,+39,+36,+2,+32,-5,
-4,-6,+1,-36,-10,-9,-16,-7,-15,-8,-20,-39,-57,-32,-13,
-42,-13,+57,+45,+56,+74,+0,+67,+67,+11,+51,-8,+50,-9,-8,
+51,-25,-18,-14,-17,-32,+84,-34,-46,+84,-43,-35,-51,-37,+5,
+54,+8,+27,+84,-41,-20,-47,-19,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+20,-45,+24,+17,-84,+35,+24,-60,+18,+14,+28,+12,+34,
+84,+32,+0,+0,+29,+0,+0,+0,+0,+0,+0,+0,+0,+0,-3,
+51,+4,+58,-84,+45,+4,+9,+3,+6,+57,+5,+47,+84,-18,-10,
+84,-4,+29,+57,+35,+49,-84,+37,+30,+22,+6,+10,+51,+14,+77,
+0,+62,+0,+64,+5,+28,+1,+2,-4,-72,-25,+84,+0,+63,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+65,+0,-20,+0,+0,+0,+84,
+0,+72,+54,+67,+41,+78,+84,+84,+84,+0,+84,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+39,-36,-8,+84,+0,+0,+74,+0,+0,+54,
+61,+48,+34,+0,+19,+77,+84,+52,+28,+0,+19,+0,+0,+0,+0,
+0,+0,+60,+84,-1,+84,+84,+0,+75,+0,+33,+12,+0,+3,-28,
+0,+64,+31,+84,-25,+0,+0,+0,+0,+0,+0,+0,+0,+0,+53,
+0,+11,+0,+0,+0,+0,+0,-72,+20,+84,+20,+18,+0,+44,+45,
+0,+34,+0,+0,+0,+0,+0,+0,+0,+0,+0,-17,-45,+3,+84,
+0,+0,-28,+0,+0,+14,+63,-6,+28,+0,+76,+28,+84,+10,+2,
+84,+41,+0,+0,+0,+84,+0,-60,-7,+84,+27,+0,+0,+0,+35,
+0,+30,+51,-12,+38,+45,+84,+70,+56,+28,+0,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+51,+84,-42,-49,+0,-84,-84,+0,+0,+43,
+84,+44,+47,+0,+28,+84,+0,+42,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+16,+3,-1,+80,+84,+84,+84,+0,+58,+62,+77,+51,+57,
+51,+84,+31,+84,+84,+31,-84,+10,+0,+0,+0,+0,+0,+0,+72,
+84,+8,+84,+0,+0,+71,+0,+50,+32,+38,+10,+49,-29,+10,+45,
-48,-29,+0,+0,+0,+0,+0,+0,+0,+0,+0,+69,-28,+78,-14,
-84,-80,+0,-84,-21,+73,+42,+36,+76,+70,+24,+84,+84,+60,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+31,+69,+20,+83,+78,+71,+84,
+70,+67,+51,+68,+47,+76,+83,+68,+25,+84,+40,+45,+51,+60,+0,
+0,+0,+0,+0,+0,+65,+82,+56,+27,+81,+84,+72,+65,+56,+42,
+9,+6,+0,+0,-9,+42,+84,+12,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+59,+84,+21,+84,+0,-6,+84,+84,-9,+30,+84,-15,+84,
+84,+73,+51,+0,+65,+0,+0,+0,+0,+0,+0,+0,+0,+0,+20,
+3,-3,+42,+84,+63,+33,+28,+3,+68,+29,+51,+59,+0,+65,+69,
+67,+41,+48,+84,+24,+0,+0,+0,+53,+12,+15,+71,+68,+22,+84,
+0,+84,+48,+75,+20,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+22,+16,-10,+84,
+0,+52,+23,-45,-13,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
-84,+0,+0,+0,+0,+0,+0,-84,+31,+56,+11,+84,+0,+13,+52,
+18,+31,+0,+0,+0,+0,+0,+0,+0,+0,+0,+29,-21,-25,+84,
+0,+84,-84,+0,+16,+23,+72,-2,-26,+42,-36,+10,-37,+11,+43,
+54,+47,+0,+0,+0,+0,+0,+0,+41,+80,+16,+84,+0,+48,+67,
-37,+21,+5,+44,+0,-11,+28,-6,+30,+0,+1,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+60,+0,+13,+0,+0,+0,+0,+0,+4,+4,
+42,+8,+53,+84,+1,+3,-17,+22,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+16,-54,-12,+0,+0,+0,+14,+61,+5,+3,+68,-5,+11,
+70,+22,+5,+64,+22,+14,+15,-5,+0,+0,+0,+84,-42,-21,+8,
+56,+14,+0,+0,+72,-2,+81,+15,+33,+75,+33,+0,+84,+28,-47,
+0,-25,+0,+0,+0,+0,+0,+0,+0,+0,+0,+19,+58,+15,+12,
+84,-3,-11,+10,-22,+25,-84,+28,+74,+84,-43,+25,+84,+9,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+11,+27,+26,+22,+49,+6,-1,
+34,+13,+53,+66,+54,+65,+84,+16,+0,+0,+36,+52,-10,+53,+16,
+34,+37,-8,-84,+24,+34,+69,+25,+34,+84,+8,+10,+49,+6,+34,
+28,-1,-17,+19,+84,+0,-56,+24,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+19,+8,+12,+4,-73,-38,+42,-36,-16,+49,+43,+22,+76,
+71,+68,+14,+48,+20,+0,+0,+0,+0,+0,+0,+0,+0,+0,+44,
+65,+15,+59,-42,+30,+42,+0,+19,+68,+70,+54,+67,+71,+71,+80,
+84,+41,+61,+61,+43,+37,+0,+47,+47,+0,-13,+52,+59,+53,+58,
-59,+25,+61,+16,+39,+18,+74,+18,+84,-84,-74,-72,+0,-7,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+19,+4,+10,-7,+0,+5,-32,
+28,-5,+37,+60,+32,+18,+84,-58,-63,+0,+32,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+17,+29,+16,+32,+0,+35,-2,+51,+16,+83,
+71,+45,+74,+56,+67,+38,+28,+41,+54,+38,+68,+78,+0,+65,+30,
+36,+49,+24,+50,-7,+54,+0,+52,+19,+80,+1,+6,-17,-9,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+35,
+32,+10,+15,+14,+21,+19,+42,-24,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+23,+26,+12,+51,
+10,+49,+28,+15,+37,+42,+73,+54,+60,+84,+45,+45,-24,+45,+59,
+55,+48,+51,+28,+3,+31,+27,-15,+44,+52,+30,+53,+41,+49,+40,
+10,+39,+26,+43,-4,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+36,+73,+27,+47,+10,-5,+38,+18,-6,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+47,+55,+29,+62,+39,+44,+49,+29,+22,+64,+81,+36,+46,
+46,+8,+43,+19,+18,+58,+46,+42,+42,+28,+6,+38,-7,+6,+53,
+67,+42,+58,+42,+34,+48,+30,+16,+15,-21,+3,+0,+0,+0,+37,
-18,+21,+0,+0,+0,+0,+0,+0,+0,+0,+0,+41,+60,+34,+25,
+49,+12,+14,+12,+6,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+18,+60,+20,+24,+23,+32,+44,
+47,+21,+54,+84,+53,-34,+3,+2,+71,+78,+33,+44,+53,+24,+43,
+8,+23,+17,+23,+4,+47,+19,+43,+51,+41,+34,+47,+51,+37,+11,
-5,+5,+0,+0,+0,+10,+26,+0,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+5,+17,-14,-7,+0,-35,+26,+52,+8,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+10,
+13,+5,+38,+0,+67,+16,+59,+23,+24,-28,+42,+84,+0,+56,-15,
+84,+57,+45,+21,+60,+45,+0,+46,-3,+25,+6,+18,+40,-4,+22,
+84,+36,+7,+45,+25,+27,+0,-8,+0,+0,+0,+24,-84,-26,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+25,+84,+28,+84,+0,+5,-4,
-5,-19,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+26,+0,+10,+84,+0,+6,+21,-5,-5,+84,
+0,-12,+84,+0,-42,-8,-38,-12,+72,+0,+32,+34,+0,+28,+36,
-6,-8,+23,+42,-3,+32,-34,+29,+5,+0,-5,+40,-11,+26,+0,
+0,+0,-12,-84,-11,+0,+0,+0,+0,+0,+0,+0,+0,+0,-3,
+29,-2,+25,+60,+12,-11,+36,-20,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+10,+0,+23,+23,
+52,+27,+12,-34,-5,+60,+21,+67,+78,+64,+51,+4,+51,-1,+53,
+66,+60,+35,+63,+13,+9,+51,+6,+2,+69,+11,+18,+2,+19,-7,
+2,-21,-2,-5,-28,+0,+0,+0,+7,+0,+6,+0,+0,+0,+0,
+0,+0,+0,+0,+0,-13,-15,+1,+72,+0,+0,+22,+0,+6,+47,
+60,+34,+0,+0,+0,+59,+0,+68,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+19,+0,+8,-26,+0,+42,-4,+65,+1,+41,+84,+55,+0,
+0,+0,+53,+0,+52,+48,+84,+60,+0,+0,+0,+42,-84,+41,+40,
+76,+39,+56,+0,+0,+41,+45,+38,+23,+25,-15,+0,+0,+0,+11,
-44,+24,+0,+0,+0,+0,+0,+0,+0,+0,+0,+29,+78,+2,+84,
+84,+84,+22,-17,+18,+83,+84,+84,+0,+0,+0,+72,+84,+48,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+54,+84,+22,+0,-84,+84,+52,
+45,+40,+64,-11,+64,+0,+0,+0,+70,+31,+14,+50,+72,+70,+0,
+0,+0,+54,+55,+68,+63,+77,+24,+75,+84,+84,+66,+53,+48,+4,
+9,-33,+0,+0,+0,-11,+0,-84,+0,+0,+0,+0,+0,+0,+0,
+0,+0,-22,-63,-9,+0,+0,+0,+23,+0,-21,+48,+0,+28,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+28,
+62,+36,+0,+0,+0,+61,+0,+23,+20,+0,+64,+0,+0,+0,+0,
+0,-58,+53,+0,+44,+0,+0,+0,+0,+0,+0,+54,+84,+21,+84,
+0,+0,+72,+0,+44,+12,+60,+59,+0,+0,+0,+16,+84,+1,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+24,-28,-13,+0,+0,+0,+3,
-21,-31,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+19,+84,+29,+0,+0,+0,+32,+51,+52,+62,
+84,+14,+0,+0,+0,+12,+70,+84,+32,+79,+18,+0,+0,+0,+53,
+59,+48,+71,+56,+81,+84,+0,+28,+51,+51,+30,+5,+0,-20,+0,
+0,+0,+42,-51,-31,+0,+0,+0,+0,+0,+0,+0,+0,+0,+27,
+84,+15,+0,+0,+0,+0,-15,-18,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+21,+0,+28,+0,
+0,+0,+46,+49,+33,+46,+0,+47,+0,+0,+0,+73,+63,+36,+0,
+0,+0,+0,+0,+0,+40,+37,+19,+66,+81,+49,+52,+55,+31,+60,
+57,+44,+82,+0,-7,+0,+0,+0,+44,+0,+21,+0,+0,+0,+0,
+0,+0,+0,+0,+0,+23,+0,-35,+0,+0,+0,-8,-13,-24,+0,
+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,+0,
+0,+0,+77,+0,+84,+0,+0,+0,+52,-34,+18,+84,+0,+0,+0,
+0,+0,+18,+0,+31,+0,+0,+0,+0,+0,+0,+56,+0,+43,+84,
+0,+28,+84,+0,+47,+44,+70,+22,+14,+20,+30,+69,+0,+84,+6,
+0,+45,-10,+84,+84,+0,+0,+0,+39,-84,+19,+13,+51,+3,+0,
-84,-56,-11,+49,+12,+15,+53,+73,+0,+0,+84,+21,+0,+65,+46,
+0,+54,+0,+0,+0,+0,+67,+5,+20,+49,+48,+66,+0,-58,+35,
+84,+24,+36,+24,-11,+84,+0,+84,+14,+84,-7,+31,+0,+23,+0,
+0,+0,+12,+34,+32,+38,+81,+44,+84,+84,+14,+54,+64,+52,+40,
-11,+6,+84,-22,+36,+42,+3,-5,+14,+33,+13,+0,+0,+0,+64,
+84,-11,+13,+6,+3,-84,-46,-31,+23,+29,+6,+66,+18,+29,+84,
-8,-19,+49,+73,+26,+46,+36,+40,+0,+0,+0,+57,+34,+19,+56,
+52,+30,+84,+75,+84,+17,+35,+41,+59,+73,+33,+84,+77,+84,+65,
+40,+27,+77,+81,+25,+0,+0,+0,+50,+21,+18,+79,+82,+42,+84,
+84,+80,+71,+74,+39,+10,-11,+8,+42,-76,+0,+33,-18,+19,+28,
+28,+25,+20,+0,+32,+15,+54,+17,+23,+25,+19,+3,-84,-7,+22,
+20,+10,+34,+62,+48,+28,+84,+74,+59,+25,+48,+33,-10,+33,+34,
+80,+19,+21,+40,+8,+15,+45,+17,+47,+55,+48,+29,+40,+35,+50,
+68,+51,+84,+17,+68,+55,+42,+57,+47,+79,+49,+62,+0,+45,+27,
+45,+31,+57,+75,+57,+58,+84,+68,+71,+63,+66
];
Diag8 = [
+0,+0,-10,-8,-8,-10,+0,-10,-8,-8,-8,-10,-16,-8,-10,
+0,-10,+0,+0,+0,-10,-21,-10,+0,+0,+2,-8,-8,-8,-18,
-16,-16,-10,+0,-10,-16,-16,-16,-10,-16,-8,-10,+0,-10,+0,
+0,+0,-10,-21,-10,+8,+8,+8,+0,+0,+0,-10,-8,-8,-10,
+0,-10,-21,-21,-21,-10,-21,-10,+0,+8,+2,+0,+0,+0,+2,
-8,+2,+0,+0,+2,-8,-8,-8,-18,-16,-16,-18,-8,-18,-16,
-16,-16,-18,-24,-16,-10,+0,-10,+0,+0,+0,-10,-21,-10,-8,
-8,-5,-16,-16,-16,-26,-24,-24,-10,+0,-10,-16,-16,-16,-10,
-16,-8,-10,+0,-10,+0,+0,+0,-10,-21,-10,+8,+8,+8,+0,
+0,+0,-10,-8,-8,-10,+0,-10,-21,-21,-21,-10,-21,-10,+8,
+16,+8,+8,+8,+8,+8,-2,+8,+8,+8,+10,+0,+0,+0,-10,
-8,-8,-10,+0,-10,-8,-8,-8,-10,-16,-8,-10,+0,-10,+0,
+0,+0,-10,-21,-10,-13,-13,-10,-21,-21,-21,-29,-29,-29,-10,
+0,-10,-21,-21,-21,-10,-21,-10,+0,+8,+2,+8,+8,+8,+2,
-8,+2,+8,+8,+10,+0,+0,+0,-10,-8,-8,+2,+13,+2,-8,
-8,-8,+2,-8,+2,+0,+8,+2,+0,+0,+0,+2,-8,+2,+0,
+0,+2,-8,-8,-8,-18,-16,-16,-18,-8,-18,-16,-16,-16,-18,
-24,-16,-18,-8,-18,-8,-8,-8,-18,-29,-18,-8,-8,-5,-16,
-16,-16,-26,-24,-24,-18,-8,-18,-24,-24,-24,-18,-24,-16,-10,
+0,-10,+0,+0,+0,-10,-21,-10,+8,+8,+8,+0,+0,+0,-10,
-8,-8,-10,+0,-10,-21,-21,-21,-10,-21,-10,-8,+0,-5,-8,
-8,-8,-5,-16,-5,-8,-8,-5,-16,-16,-16,-26,-24,-24,-26,
-16,-26,-24,-24,-24,-26,-32,-24,-10,+0,-10,+0,+0,+0,-10,
-21,-10,-8,-8,-5,-16,-16,-16,-26,-24,-24,-10,+0,-10,-16,
-16,-16,-10,-16,-8,-10,+0,-10,+0,+0,+0,-10,-21,-10,+8,
+8,+8,+0,+0,+0,-10,-8,-8,-10,+0,-10,-21,-21,-21,-10,
-21,-10,+8,+16,+8,+8,+8,+8,+8,-2,+8,+8,+8,+10,+0,
+0,+0,-10,-8,-8,-10,+0,-10,-8,-8,-8,-10,-16,-8,-10,
+0,-10,+0,+0,+0,-10,-21,-10,-13,-13,-10,-21,-21,-21,-29,
-29,-29,-10,+0,-10,-21,-21,-21,-10,-21,-10,+8,+16,+8,+16,
+16,+16,+8,-2,+8,+16,+16,+18,+8,+8,+8,-2,+0,+0,+8,
+18,+8,-2,-2,-2,+8,-2,+8,+8,+16,+10,+8,+8,+8,+10,
+0,+10,+8,+8,+10,+0,+0,+0,-10,-8,-8,-10,+0,-10,-8,
-8,-8,-10,-16,-8,-10,+0,-10,+0,+0,+0,-10,-21,-10,+0,
+0,+2,-8,-8,-8,-18,-16,-16,-10,+0,-10,-16,-16,-16,-10,
-16,-8,-10,+0,-10,+0,+0,+0,-10,-21,-10,+8,+8,+8,+0,
+0,+0,-10,-8,-8,-10,+0,-10,-21,-21,-21,-10,-21,-10,-13,
-5,-10,-13,-13,-13,-10,-21,-10,-13,-13,-10,-21,-21,-21,-31,
-29,-29,-29,-18,-29,-29,-29,-29,-29,-37,-29,-10,+0,-10,+0,
+0,+0,-10,-21,-10,-13,-13,-10,-21,-21,-21,-29,-29,-29,-10,
+0,-10,-21,-21,-21,-10,-21,-10,+0,+8,+2,+8,+8,+8,+2,
-8,+2,+16,+16,+18,+8,+8,+8,-2,+0,+0,+2,+13,+2,-8,
-8,-8,+2,-8,+2,+8,+16,+10,+8,+8,+8,+10,+0,+10,+8,
+8,+10,+0,+0,+0,-10,-8,-8,-10,+0,-10,-8,-8,-8,-10,
-16,-8,+2,+13,+2,+13,+13,+13,+2,-8,+2,+0,+0,+2,-8,
-8,-8,-16,-16,-16,+2,+13,+2,-8,-8,-8,+2,-8,+2,+0,
+8,+2,+8,+8,+8,+2,-8,+2,+8,+8,+10,+0,+0,+0,-10,
-8,-8,+2,+13,+2,-8,-8,-8,+2,-8,+2,+0,+8,+2,+0,
+0,+0,+2,-8,+2,+0,+0,+2,-8,-8,-8,-18,-16,-16,-18,
-8,-18,-16,-16,-16,-18,-24,-16,-18,-8,-18,-8,-8,-8,-18,
-29,-18,-8,-8,-5,-16,-16,-16,-26,-24,-24,-18,-8,-18,-24,
-24,-24,-18,-24,-16,-18,-8,-18,-8,-8,-8,-18,-29,-18,+0,
+0,+0,-8,-8,-8,-18,-16,-16,-18,-8,-18,-29,-29,-29,-18,
-29,-18,-8,+0,-5,-8,-8,-8,-5,-16,-5,-8,-8,-5,-16,
-16,-16,-26,-24,-24,-26,-16,-26,-24,-24,-24,-26,-32,-24,-18,
-8,-18,-8,-8,-8,-18,-29,-18,-16,-16,-13,-24,-24,-24,-34,
-32,-32,-18,-8,-18,-24,-24,-24,-18,-24,-16,-10,+0,-10,+0,
+0,+0,-10,-21,-10,+8,+8,+8,+0,+0,+0,-10,-8,-8,-10,
+0,-10,-21,-21,-21,-10,-21,-10,+8,+16,+8,+8,+8,+8,+8,
-2,+8,+8,+8,+10,+0,+0,+0,-10,-8,-8,-10,+0,-10,-8,
-8,-8,-10,-16,-8,-10,+0,-10,+0,+0,+0,-10,-21,-10,-13,
-13,-10,-21,-21,-21,-29,-29,-29,-10,+0,-10,-21,-21,-21,-10,
-21,-10,-8,+0,-5,+0,+0,+0,-5,-16,-5,+0,+0,+2,-8,
-8,-8,-18,-16,-16,-5,+5,-5,-16,-16,-16,-5,-16,-5,-8,
+0,-5,-8,-8,-8,-5,-16,-5,-8,-8,-5,-16,-16,-16,-26,
-24,-24,-26,-16,-26,-24,-24,-24,-26,-32,-24,-26,-16,-26,-16,
-16,-16,-26,-37,-26,-16,-16,-13,-24,-24,-24,-34,-32,-32,-26,
-16,-26,-32,-32,-32,-26,-32,-24,-10,+0,-10,+0,+0,+0,-10,
-21,-10,+8,+8,+8,+0,+0,+0,-10,-8,-8,-10,+0,-10,-21,
-21,-21,-10,-21,-10,-8,+0,-5,-8,-8,-8,-5,-16,-5,-8,
-8,-5,-16,-16,-16,-26,-24,-24,-26,-16,-26,-24,-24,-24,-26,
-32,-24,-10,+0,-10,+0,+0,+0,-10,-21,-10,-8,-8,-5,-16,
-16,-16,-26,-24,-24,-10,+0,-10,-16,-16,-16,-10,-16,-8,+0,
+10,+0,+10,+10,+10,+0,-10,+0,+18,+18,+18,+10,+10,+10,+0,
+2,+2,+0,+10,+0,-10,-10,-10,+0,-10,+0,+18,+26,+18,+18,
+18,+18,+18,+8,+18,+18,+18,+21,+10,+10,+10,+0,+2,+2,+0,
+10,+0,+2,+2,+2,+0,-5,+2,+0,+10,+0,+10,+10,+10,+0,
-10,+0,-2,-2,+0,-10,-10,-10,-18,-18,-18,+0,+10,+0,-10,
-10,-10,+0,-10,+0,+18,+26,+18,+26,+26,+26,+18,+8,+18,+26,
+26,+29,+18,+18,+18,+8,+10,+10,+18,+29,+18,+8,+8,+8,+18,
+8,+18,+18,+26,+21,+18,+18,+18,+21,+10,+21,+18,+18,+21,+10,
+10,+10,+0,+2,+2,+0,+10,+0,+2,+2,+2,+0,-5,+2,+0,
+10,+0,+10,+10,+10,+0,-10,+0,+10,+10,+13,+2,+2,+2,-8,
-5,-5,+0,+10,+0,-5,-5,-5,+0,-5,+2,+0,+10,+0,+10,
+10,+10,+0,-10,+0,+18,+18,+18,+10,+10,+10,+0,+2,+2,+0,
+10,+0,-10,-10,-10,+0,-10,+0,-2,+5,+0,-2,-2,-2,+0,
-10,+0,-2,-2,+0,-10,-10,-10,-21,-18,-18,-18,-8,-18,-18,
-18,-18,-18,-26,-18,+0,+10,+0,+10,+10,+10,+0,-10,+0,-2,
-2,+0,-10,-10,-10,-18,-18,-18,+0,+10,+0,-10,-10,-10,+0,
-10,+0,+18,+26,+18,+26,+26,+26,+18,+8,+18,+34,+34,+37,+26,
+26,+26,+16,+18,+18,+18,+29,+18,+8,+8,+8,+18,+8,+18,+26,
+34,+29,+26,+26,+26,+29,+18,+29,+26,+26,+29,+18,+18,+18,+8,
+10,+10,+8,+18,+8,+10,+10,+10,+8,+2,+10,+18,+29,+18,+29,
+29,+29,+18,+8,+18,+16,+16,+18,+8,+8,+8,+0,+0,+0,+18,
+29,+18,+8,+8,+8,+18,+8,+18,+18,+26,+21,+26,+26,+26,+21,
+10,+21,+26,+26,+29,+18,+18,+18,+8,+10,+10,+21,+31,+21,+10,
+10,+10,+21,+10,+21,+18,+26,+21,+18,+18,+18,+21,+10,+21,+18,
+18,+21,+10,+10,+10,+0,+2,+2,+0,+10,+0,+2,+2,+2,+0,
-5,+2,+0,+10,+0,+10,+10,+10,+0,-10,+0,+10,+10,+13,+2,
+2,+2,-8,-5,-5,+0,+10,+0,-5,-5,-5,+0,-5,+2,+0,
+10,+0,+10,+10,+10,+0,-10,+0,+18,+18,+18,+10,+10,+10,+0,
+2,+2,+0,+10,+0,-10,-10,-10,+0,-10,+0,+10,+18,+13,+10,
+10,+10,+13,+2,+13,+10,+10,+13,+2,+2,+2,-8,-5,-5,-8,
+2,-8,-5,-5,-5,-8,-13,-5,+0,+10,+0,+10,+10,+10,+0,
-10,+0,+2,+2,+5,-5,-5,-5,-16,-13,-13,+0,+10,+0,-5,
-5,-5,+0,-5,+2,+0,+10,+0,+10,+10,+10,+0,-10,+0,+18,
+18,+18,+10,+10,+10,+0,+2,+2,+0,+10,+0,-10,-10,-10,+0,
-10,+0,+18,+26,+18,+18,+18,+18,+18,+8,+18,+18,+18,+21,+10,
+10,+10,+0,+2,+2,+0,+10,+0,+2,+2,+2,+0,-5,+2,+0,
+10,+0,+10,+10,+10,+0,-10,+0,-2,-2,+0,-10,-10,-10,-18,
-18,-18,+0,+10,+0,-10,-10,-10,+0,-10,+0,-2,+5,+0,+5,
+5,+5,+0,-10,+0,+5,+5,+8,-2,-2,-2,-13,-10,-10,+0,
+10,+0,-10,-10,-10,+0,-10,+0,-2,+5,+0,-2,-2,-2,+0,
-10,+0,-2,-2,+0,-10,-10,-10,-21,-18,-18,-21,-10,-21,-18,
-18,-18,-21,-26,-18,-18,-8,-18,-8,-8,-8,-18,-29,-18,-10,
-10,-8,-18,-18,-18,-29,-26,-26,-18,-8,-18,-26,-26,-26,-18,
-26,-18,+0,+10,+0,+10,+10,+10,+0,-10,+0,+18,+18,+18,+10,
+10,+10,+0,+2,+2,+0,+10,+0,-10,-10,-10,+0,-10,+0,-2,
+5,+0,-2,-2,-2,+0,-10,+0,-2,-2,+0,-10,-10,-10,-21,
-18,-18,-18,-8,-18,-18,-18,-18,-18,-26,-18,+0,+10,+0,+10,
+10,+10,+0,-10,+0,-2,-2,+0,-10,-10,-10,-18,-18,-18,+0,
+10,+0,-10,-10,-10,+0,-10,+0,+8,+16,+10,+16,+16,+16,+10,
+0,+10,+24,+24,+26,+16,+16,+16,+5,+8,+8,+10,+21,+10,+0,
+0,+0,+10,+0,+10,+24,+32,+26,+24,+24,+24,+26,+16,+26,+24,
+24,+26,+16,+16,+16,+5,+8,+8,+5,+16,+5,+8,+8,+8,+5,
+0,+8,+10,+21,+10,+21,+21,+21,+10,+0,+10,+8,+8,+10,+0,
+0,+0,-8,-8,-8,+10,+21,+10,+0,+0,+0,+10,+0,+10,+16,
+24,+18,+24,+24,+24,+18,+8,+18,+24,+24,+26,+16,+16,+16,+5,
+8,+8,+18,+29,+18,+8,+8,+8,+18,+8,+18,+16,+24,+18,+16,
+16,+16,+18,+8,+18,+16,+16,+18,+8,+8,+8,-2,+0,+0,-2,
+8,-2,+0,+0,+0,-2,-8,+0,-2,+8,-2,+8,+8,+8,-2,
-13,-2,+8,+8,+10,+0,+0,+0,-10,-8,-8,-2,+8,-2,-8,
-8,-8,-2,-8,+0,+10,+21,+10,+21,+21,+21,+10,+0,+10,+29,
+29,+29,+21,+21,+21,+10,+13,+13,+10,+21,+10,+0,+0,+0,+10,
+0,+10,+8,+16,+10,+8,+8,+8,+10,+0,+10,+8,+8,+10,+0,
+0,+0,-10,-8,-8,-8,+2,-8,-8,-8,-8,-8,-16,-8,+10,
+21,+10,+21,+21,+21,+10,+0,+10,+8,+8,+10,+0,+0,+0,-8,
-8,-8,+10,+21,+10,+0,+0,+0,+10,+0,+10,+8,+16,+10,+16,
+16,+16,+10,+0,+10,+24,+24,+26,+16,+16,+16,+5,+8,+8,+10,
+21,+10,+0,+0,+0,+10,+0,+10,+16,+24,+18,+16,+16,+16,+18,
+8,+18,+16,+16,+18,+8,+8,+8,-2,+0,+0,-2,+8,-2,+0,
+0,+0,-2,-8,+0,+10,+21,+10,+21,+21,+21,+10,+0,+10,+8,
+8,+10,+0,+0,+0,-8,-8,-8,+10,+21,+10,+0,+0,+0,+10,
+0,+10,+8,+16,+10,+16,+16,+16,+10,+0,+10,+16,+16,+18,+8,
+8,+8,-2,+0,+0,+10,+21,+10,+0,+0,+0,+10,+0,+10,+8,
+16,+10,+8,+8,+8,+10,+0,+10,+8,+8,+10,+0,+0,+0,-10,
-8,-8,-10,+0,-10,-8,-8,-8,-10,-16,-8,-10,+0,-10,+0,
+0,+0,-10,-21,-10,+0,+0,+2,-8,-8,-8,-18,-16,-16,-10,
+0,-10,-16,-16,-16,-10,-16,-8,-10,+0,-10,+0,+0,+0,-10,
-21,-10,+8,+8,+8,+0,+0,+0,-10,-8,-8,-10,+0,-10,-21,
-21,-21,-10,-21,-10,+0,+8,+2,+0,+0,+0,+2,-8,+2,+0,
+0,+2,-8,-8,-8,-18,-16,-16,-18,-8,-18,-16,-16,-16,-18,
-24,-16,-10,+0,-10,+0,+0,+0,-10,-21,-10,-8,-8,-5,-16,
-16,-16,-26,-24,-24,-10,+0,-10,-16,-16,-16,-10,-16,-8,-10,
+0,-10,+0,+0,+0,-10,-21,-10,+8,+8,+8,+0,+0,+0,-10,
-8,-8,-10,+0,-10,-21,-21,-21,-10,-21,-10,+8,+16,+8,+8,
+8,+8,+8,-2,+8,+8,+8,+10,+0,+0,+0,-10,-8,-8,-10,
+0,-10,-8,-8,-8,-10,-16,-8,-10,+0,-10,+0,+0,+0,-10,
-21,-10,-13,-13,-10,-21,-21,-21,-29,-29,-29,-10,+0,-10,-21,
-21,-21,-10,-21,-10,+0,+8,+2,+8,+8,+8,+2,-8,+2,+8,
+8,+10,+0,+0,+0,-10,-8,-8,+2,+13,+2,-8,-8,-8,+2,
-8,+2,+0,+8,+2,+0,+0,+0,+2,-8,+2,+0,+0,+2,-8,
-8,-8,-18,-16,-16,-18,-8,-18,-16,-16,-16,-18,-24,-16,-18,
-8,-18,-8,-8,-8,-18,-29,-18,-8,-8,-5,-16,-16,-16,-26,
-24,-24,-18,-8,-18,-24,-24,-24,-18,-24,-16,-10,+0,-10,+0,
+0,+0,-10,-21,-10,+8,+8,+8,+0,+0,+0,-10,-8,-8,-10,
+0,-10,-21,-21,-21,-10,-21,-10,-8,+0,-5,-8,-8,-8,-5,
-16,-5,-8,-8,-5,-16,-16,-16,-26,-24,-24,-26,-16,-26,-24,
-24,-24,-26,-32,-24,-10,+0,-10,+0,+0,+0,-10,-21,-10,-8,
-8,-5,-16,-16,-16,-26,-24,-24,-10,+0,-10,-16,-16,-16,-10,
-16,-8,+0,+10,+0,+10,+10,+10,+0,-10,+0,+18,+18,+18,+10,
+10,+10,+0,+2,+2,+0,+10,+0,-10,-10,-10,+0,-10,+0,+18,
+26,+18,+18,+18,+18,+18,+8,+18,+18,+18,+21,+10,+10,+10,+0,
+2,+2,+0,+10,+0,+2,+2,+2,+0,-5,+2,+0,+10,+0,+10,
+10,+10,+0,-10,+0,-2,-2,+0,-10,-10,-10,-18,-18,-18,+0,
+10,+0,-10,-10,-10,+0,-10,+0,+18,+26,+18,+26,+26,+26,+18,
+8,+18,+26,+26,+29,+18,+18,+18,+8,+10,+10,+18,+29,+18,+8,
+8,+8,+18,+8,+18,+18,+26,+21,+18,+18,+18,+21,+10,+21,+18,
+18,+21,+10,+10,+10,+0,+2,+2,+0,+10,+0,+2,+2,+2,+0,
-5,+2,+0,+10,+0,+10,+10,+10,+0,-10,+0,+10,+10,+13,+2,
+2,+2,-8,-5,-5,+0,+10,+0,-5,-5,-5,+0,-5,+2,+0,
+10,+0,+10,+10,+10,+0,-10,+0,+18,+18,+18,+10,+10,+10,+0,
+2,+2,+0,+10,+0,-10,-10,-10,+0,-10,+0,-2,+5,+0,-2,
-2,-2,+0,-10,+0,-2,-2,+0,-10,-10,-10,-21,-18,-18,-18,
-8,-18,-18,-18,-18,-18,-26,-18,+0,+10,+0,+10,+10,+10,+0,
-10,+0,-2,-2,+0,-10,-10,-10,-18,-18,-18,+0,+10,+0,-10,
-10,-10,+0,-10,+0,+0,+8,+2,+8,+8,+8,+2,-8,+2,+16,
+16,+18,+8,+8,+8,-2,+0,+0,+2,+13,+2,-8,-8,-8,+2,
-8,+2,+8,+16,+10,+8,+8,+8,+10,+0,+10,+8,+8,+10,+0,
+0,+0,-10,-8,-8,-10,+0,-10,-8,-8,-8,-10,-16,-8,+2,
+13,+2,+13,+13,+13,+2,-8,+2,+0,+0,+2,-8,-8,-8,-16,
-16,-16,+2,+13,+2,-8,-8,-8,+2,-8,+2,+0,+8,+2,+8,
+8,+8,+2,-8,+2,+8,+8,+10,+0,+0,+0,-10,-8,-8,+2,
+13,+2,-8,-8,-8,+2,-8,+2,+0,+8,+2,+0,+0,+0,+2,
-8,+2,+0,+0,+2,-8,-8,-8,-18,-16,-16,-18,-8,-18,-16,
-16,-16,-18,-24,-16,-18,-8,-18,-8,-8,-8,-18,-29,-18,-8,
-8,-5,-16,-16,-16,-26,-24,-24,-18,-8,-18,-24,-24,-24,-18,
-24,-16,-18,-8,-18,-8,-8,-8,-18,-29,-18,+0,+0,+0,-8,
-8,-8,-18,-16,-16,-18,-8,-18,-29,-29,-29,-18,-29,-18,-8,
+0,-5,-8,-8,-8,-5,-16,-5,-8,-8,-5,-16,-16,-16,-26,
-24,-24,-26,-16,-26,-24,-24,-24,-26,-32,-24,-18,-8,-18,-8,
-8,-8,-18,-29,-18,-16,-16,-13,-24,-24,-24,-34,-32,-32,-18,
-8,-18,-24,-24,-24,-18,-24,-16,+0,+10,+0,+10,+10,+10,+0,
-10,+0,+18,+18,+18,+10,+10,+10,+0,+2,+2,+0,+10,+0,-10,
-10,-10,+0,-10,+0,+18,+26,+18,+18,+18,+18,+18,+8,+18,+18,
+18,+21,+10,+10,+10,+0,+2,+2,+0,+10,+0,+2,+2,+2,+0,
-5,+2,+0,+10,+0,+10,+10,+10,+0,-10,+0,-2,-2,+0,-10,
-10,-10,-18,-18,-18,+0,+10,+0,-10,-10,-10,+0,-10,+0,+0,
+8,+2,+8,+8,+8,+2,-8,+2,+8,+8,+10,+0,+0,+0,-10,
-8,-8,+2,+13,+2,-8,-8,-8,+2,-8,+2,+0,+8,+2,+0,
+0,+0,+2,-8,+2,+0,+0,+2,-8,-8,-8,-18,-16,-16,-18,
-8,-18,-16,-16,-16,-18,-24,-16,-18,-8,-18,-8,-8,-8,-18,
-29,-18,-8,-8,-5,-16,-16,-16,-26,-24,-24,-18,-8,-18,-24,
-24,-24,-18,-24,-16,+0,+10,+0,+10,+10,+10,+0,-10,+0,+18,
+18,+18,+10,+10,+10,+0,+2,+2,+0,+10,+0,-10,-10,-10,+0,
-10,+0,+0,+8,+2,+0,+0,+0,+2,-8,+2,+0,+0,+2,-8,
-8,-8,-18,-16,-16,-18,-8,-18,-16,-16,-16,-18,-24,-16,+0,
+10,+0,+10,+10,+10,+0,-10,+0,+0,+0,+2,-8,-8,-8,-18,
-16,-16,+0,+10,+0,-8,-8,-8,+0,-8,+0
];
Diag7 = [
+0,+0,-9,-6,-6,-9,+0,-9,-6,-6,-6,-9,-12,-6,-10,+0,-10,
-1,+0,-1,-12,-19,-10,-3,+0,-3,-12,-7,-1,-18,-15,-14,
-10,-1,-9,-13,-12,-13,-10,-13,-7,-10,+0,-10,+0,+0,-1,
-12,-19,-11,+3,+8,+5,-3,+0,-4,-8,-9,-6,-10,+0,-9,
-18,-19,-21,-11,-19,-10,+0,+6,+3,+0,+0,+0,+3,-6,+3,
+0,+0,+3,-6,-6,-6,-15,-12,-12,-15,-6,-15,-12,-12,-12,
-15,-17,-12,-10,+0,-10,+0,+0,-1,-12,-19,-11,-6,-6,-6,
-13,-12,-13,-25,-21,-24,-10,-1,-10,-13,-13,-14,-11,-13,-7,
-9,+0,-9,+1,+1,+0,-11,-20,-11,+15,+8,+10,-5,+1,-2,
-5,-7,-3,-9,+0,-8,-19,-19,-20,-11,-20,-10,+6,+12,+6,
+6,+6,+6,+6,-3,+6,+6,+6,+9,+0,+0,+0,-9,-6,-6,
-9,+0,-9,-6,-6,-6,-9,-12,-6,-9,+1,-9,+0,+0,+0,
-11,-19,-11,-11,-13,-16,-17,-19,-13,-32,-26,-18,-8,+0,-8,
-20,-19,-20,-10,-19,-10,+1,+8,+1,+5,+6,+2,+4,-7,+3,
-3,+10,+17,+4,+0,+0,+0,-8,+3,+5,+13,+6,+0,-9,-10,
+3,-7,+5,+0,+6,+3,+0,+0,+0,+3,-6,+3,+0,+0,+3,
-6,-6,-6,-15,-12,-12,-15,-6,-15,-12,-12,-12,-15,-17,-12,
-18,-7,-17,-10,-8,-11,-20,-26,-17,-6,-10,-3,-20,-15,-20,
-20,-22,-9,-18,-8,-17,-23,-21,-23,-18,-21,-14,-10,+0,-10,
+0,+0,-1,-12,-20,-12,+4,+7,+5,-4,+0,-4,-15,-7,-3,
-10,-1,-9,-19,-19,-20,-11,-20,-11,-6,+0,-3,-6,-6,-6,
-3,-12,-3,-6,-6,-3,-12,-12,-12,-20,-17,-17,-20,-12,-20,
-17,-17,-17,-20,-23,-17,-10,+0,-10,-1,+0,+0,-12,-19,-11,
-11,-8,-12,-19,-13,-12,-28,-21,-15,-9,+0,-9,-14,-13,-12,
-11,-14,-7,+1,+11,+3,+13,+11,+13,+0,-9,+0,+17,+18,+20,
+17,+10,+11,-2,+1,+6,+2,+10,+3,-9,-10,-10,+0,-10,+0,
+15,+20,+15,+15,+15,+15,+15,+6,+15,+15,+15,+17,+9,+9,+9,
+0,+3,+3,+0,+9,+0,+3,+3,+3,+0,-3,+3,+2,+11,+2,
+12,+11,+12,-1,-9,+0,+3,-3,+4,-2,-10,-10,-23,-17,-6,
+2,+11,+3,-9,-10,-10,+0,-10,+1,+20,+28,+20,+29,+25,+12,
+23,+10,+19,+20,+20,+23,+15,+18,+15,+6,+17,+17,+21,+32,+16,
+6,+5,+6,+23,+5,+22,+15,+20,+17,+15,+15,+15,+17,+9,+17,
+15,+15,+17,+9,+9,+9,+0,+3,+3,+0,+9,+0,+3,+3,+3,
+0,-3,+3,-7,+15,+4,+9,+8,+9,+9,-16,-9,+9,+0,+12,
+3,-3,+3,-6,-3,+6,+0,+5,-2,-3,-6,-3,+2,-12,+0,
+2,+12,+3,+12,+12,+14,+0,-8,+0,+23,+20,+16,+9,+12,+6,
-9,+6,+2,+2,+11,+3,-10,-9,-9,+1,-9,+1,-3,+3,+0,
-3,-3,-3,+0,-9,+0,-3,-3,+0,-9,-9,-9,-17,-15,-15,
-15,-6,-15,-15,-15,-15,-15,-20,-15,+2,+12,+3,+11,+12,+14,
+0,-8,+1,-9,-4,-2,-3,-9,-15,-23,-17,-23,+2,+11,+3,
-11,-10,-8,+0,-9,+1,+6,+14,+13,+18,+13,+20,+11,+0,+9,
+17,+23,+12,+20,+13,+12,+3,+2,+8,+11,+20,+14,+9,-1,+4,
+9,-1,+9,+12,+17,+15,+12,+12,+12,+15,+6,+15,+12,+12,+15,
+6,+6,+6,-3,+0,+0,-3,+6,-3,+0,+0,+0,-3,-6,+0,
+10,+19,+12,+15,+18,+26,+10,+0,+10,+6,+0,+9,-9,-1,+0,
-6,-11,-6,+11,+19,+14,-9,-1,+2,+9,+0,+11,+11,+19,+11,
+12,+13,+12,+3,-2,+12,+12,+20,+15,+6,+12,+6,-3,+0,+0,
+15,+17,+6,+9,-4,+0,+2,-4,+6,+6,+12,+9,+6,+6,+6,
+9,+0,+9,+6,+6,+9,+0,+0,+0,-9,-6,-6,-9,+0,-9,
-6,-6,-6,-9,-12,-6,-12,+4,-10,+0,+3,+0,-9,-13,-3,
+0,-4,+3,-6,-1,-6,-15,-20,-12,-11,+5,-15,-20,-13,-12,
-17,-12,-8,-9,+1,-10,-1,+0,+4,-11,-20,-13,+6,+10,+6,
+0,+1,+0,-9,-10,-6,-7,+0,-9,-15,-21,-17,-12,-20,-10,
+0,+6,+3,+0,+0,+0,+3,-6,+3,+0,+0,+3,-6,-6,-6,
-15,-12,-12,-15,-6,-15,-12,-12,-12,-15,-17,-12,-10,+0,-10,
+1,+0,+2,-12,-20,-10,-15,-5,-3,-12,-13,-12,-29,-23,-17,
-11,-1,-8,-18,-14,-20,-13,-12,-6,-1,+9,+0,+11,+10,+9,
-2,-11,-2,+20,+18,+19,+11,+10,+12,+0,+3,+8,+0,+8,+0,
-11,-11,-13,-2,-12,-2,+15,+20,+15,+15,+15,+15,+15,+6,+15,
+15,+15,+17,+9,+9,+9,+0,+3,+3,+0,+9,+0,+3,+3,+3,
+0,-3,+3,-1,+10,+0,+7,+10,+10,-2,-11,-2,-10,-5,-9,
-15,-10,-3,-21,-17,-15,+0,+9,+1,-11,-11,-10,-2,-11,-2,
+4,+11,+6,+15,+6,+8,+9,-3,+8,+6,+6,+17,+0,+3,+0,
-9,+3,-6,+10,+11,+2,-6,-6,-6,-3,-3,+4,+0,+6,+3,
+0,+0,+0,+3,-6,+3,+0,+0,+3,-6,-6,-6,-15,-12,-12,
-15,-6,-15,-12,-12,-12,-15,-17,-12,-11,-4,-6,-6,-3,-6,
-23,-18,-15,-6,+3,+6,-12,-14,-12,-20,-9,-17,-20,-15,-23,
-17,-24,-17,-17,-15,-18,+0,+10,+0,+10,+10,+9,-2,-10,-2,
+11,+18,+22,+12,+10,+6,+7,+5,+4,+1,+9,+1,-10,-10,-10,
-2,-11,-2,+0,+6,+3,+0,+0,+0,+3,-6,+3,+0,+0,+3,
-6,-6,-6,-15,-12,-12,-15,-6,-15,-12,-12,-12,-15,-17,-12,
+0,+10,+1,+9,+10,+11,-2,-10,-2,-4,-1,+0,-11,-7,-8,
-20,-14,-18,+1,+9,+1,-6,-7,-6,-1,-7,-1
];
Diag6 = [
+0,+0,-7,-5,-5,-7,+0,-7,-5,-5,-5,
-7,-10,-5,-7,+0,-7,+0,+0,+0,-7,-15,-7,+0,+0,+2,
-5,-5,-5,-12,-10,-10,-7,+0,-7,-10,-10,-10,-7,-10,-5,
-7,+0,-7,+0,+0,+0,-7,-15,-7,+5,+5,+5,+0,+0,+0,
-7,-5,-5,-7,+0,-7,-15,-15,-15,-7,-15,-7,+0,+5,+2,
+0,+0,+0,+2,-5,+2,+0,+0,+2,-5,-5,-5,-12,-10,-10,
-12,-5,-12,-10,-10,-10,-12,-15,-10,-7,+0,-7,+0,+0,+0,
-7,-15,-7,-5,-5,-3,-10,-10,-10,-18,-15,-15,-7,+0,-7,
-10,-10,-10,-7,-10,-5,+0,+7,+0,+7,+7,+7,+0,-7,+0,
+12,+12,+12,+7,+7,+7,+0,+2,+2,+0,+7,+0,-7,-7,-7,
+0,-7,+0,+12,+18,+12,+12,+12,+12,+12,+5,+12,+12,+12,+15,
+7,+7,+7,+0,+2,+2,+0,+7,+0,+2,+2,+2,+0,-3,+2,
+0,+7,+0,+7,+7,+7,+0,-7,+0,-2,-2,+0,-7,-7,-7,
-12,-12,-12,+0,+7,+0,-7,-7,-7,+0,-7,+0,+5,+10,+7,
+10,+10,+10,+7,+0,+7,+10,+10,+12,+5,+5,+5,-2,+0,+0,
+7,+15,+7,+0,+0,+0,+7,+0,+7,+5,+10,+7,+5,+5,+5,
+7,+0,+7,+5,+5,+7,+0,+0,+0,-7,-5,-5,-7,+0,-7,
-5,-5,-5,-7,-10,-5,-7,+0,-7,+0,+0,+0,-7,-15,-7,
+0,+0,+2,-5,-5,-5,-12,-10,-10,-7,+0,-7,-10,-10,-10,
-7,-10,-5,+0,+7,+0,+7,+7,+7,+0,-7,+0,+12,+12,+12,
+7,+7,+7,+0,+2,+2,+0,+7,+0,-7,-7,-7,+0,-7,+0,
+0,+5,+2,+0,+0,+0,+2,-5,+2,+0,+0,+2,-5,-5,-5,
-12,-10,-10,-12,-5,-12,-10,-10,-10,-12,-15,-10,+0,+7,+0,
+7,+7,+7,+0,-7,+0,+0,+0,+2,-5,-5,-5,-12,-10,-10,
+0,+7,+0,-5,-5,-5,+0,-5,+0
];
Diag5 = [
+0,+0,-5,-4,-4,-5,+0,-5,-4,-4,-4,-5,-7,-4,
-5,+0,-5,+0,+0,+0,-5,-11,-5,+0,+0,+2,-4,-4,-4,
-9,-7,-7,-5,+0,-5,-7,-7,-7,-5,-7,-4,+0,+5,+0,
+5,+5,+5,+0,-5,+0,+9,+9,+9,+5,+5,+5,+0,+2,+2,
+0,+5,+0,-5,-5,-5,+0,-5,+0,+4,+7,+5,+4,+4,+4,
+5,+0,+5,+4,+4,+5,+0,+0,+0,-5,-4,-4,-5,+0,-5,
-4,-4,-4,-5,-7,-4,+0,+5,+0,+5,+5,+5,+0,-5,+0,
+0,+0,+2,-4,-4,-4,-9,-7,-7,+0,+5,+0,-4,-4,-4,
+0,-4,+0
];
Diag4 = [
+0,+0,-4,-3,-3,
-3,+0,-3,-2,-3,-3,-5,-5,-3,+1,+5,+1,+4,+4,+3,
+0,-3,+0,+2,+2,+3,+0,+0,-1,-4,-3,-3,+0,+3,+0,
-2,-3,-3,-1,-3,-1
];
}
//機能: 与えられた盤面の評価値を算出する。
//備考: 白番で有利で+のデータ。黒番の時は、値を反転する。
public function Eval(board:Array, empties:int, color:int):int {
var Idx:int, Val:int, Val1:int, Val2:int, Val3:int, Val4:int;
var Val5:int, Val6:int, Val7:int, Val8:int, Val9:int, Val0:int;
//Line1
Val1 = 0;
Idx = ((((((board[A1]*3+board[B1])*3+board[C1])
*3+board[D1])*3+board[E1])*3+board[F1])
*3+board[G1])*3+board[H1];
if (Idx < 0)
Val1 -= Line1[-Idx];
else
Val1 += Line1[Idx];
Idx = ((((((board[A8]*3+board[B8])*3+board[C8])
*3+board[D8])*3+board[E8])*3+board[F8])
*3+board[G8])*3+board[H8];
if (Idx < 0)
Val1 -= Line1[-Idx];
else
Val1 += Line1[Idx];
Idx = ((((((board[A1]*3+board[A2])*3+board[A3])
*3+board[A4])*3+board[A5])*3+board[A6])
*3+board[A7])*3+board[A8];
if (Idx < 0)
Val1 -= Line1[-Idx];
else
Val1 += Line1[Idx];
Idx = ((((((board[H1]*3+board[H2])*3+board[H3])
*3+board[H4])*3+board[H5])*3+board[H6])
*3+board[H7])*3+board[H8];
if (Idx < 0)
Val1 -= Line1[-Idx];
else
Val1 += Line1[Idx];
//Line2
Val2 = 0;
Idx = ((((((board[A2]*3+board[B2])*3+board[C2])
*3+board[D2])*3+board[E2])*3+board[F2])
*3+board[G2])*3+board[H2];
if (Idx < 0)
Val2 -= Line2[-Idx];
else
Val2 += Line2[Idx];
Idx = ((((((board[A7]*3+board[B7])*3+board[C7])
*3+board[D7])*3+board[E7])*3+board[F7])
*3+board[G7])*3+board[H7];
if (Idx < 0)
Val2 -= Line2[-Idx];
else
Val2 += Line2[Idx];
Idx = ((((((board[B1]*3+board[B2])*3+board[B3])
*3+board[B4])*3+board[B5])*3+board[B6])
*3+board[B7])*3+board[B8];
if (Idx < 0)
Val2 -= Line2[-Idx];
else
Val2 += Line2[Idx];
Idx = ((((((board[G1]*3+board[G2])*3+board[G3])
*3+board[G4])*3+board[G5])*3+board[G6])
*3+board[G7])*3+board[G8];
if (Idx < 0)
Val2 -= Line2[-Idx];
else
Val2 += Line2[Idx];
//Line3
Val3 = 0;
Idx = ((((((board[A3]*3+board[B3])*3+board[C3])
*3+board[D3])*3+board[E3])*3+board[F3])
*3+board[G3])*3+board[H3];
if (Idx < 0)
Val3 -= Line3[-Idx];
else
Val3 += Line3[Idx];
Idx = ((((((board[A6]*3+board[B6])*3+board[C6])
*3+board[D6])*3+board[E6])*3+board[F6])
*3+board[G6])*3+board[H6];
if (Idx < 0)
Val3 -= Line3[-Idx];
else
Val3 += Line3[Idx];
Idx = ((((((board[C1]*3+board[C2])*3+board[C3])
*3+board[C4])*3+board[C5])*3+board[C6])
*3+board[C7])*3+board[C8];
if (Idx < 0)
Val3 -= Line3[-Idx];
else
Val3 += Line3[Idx];
Idx = ((((((board[F1]*3+board[F2])*3+board[F3])
*3+board[F4])*3+board[F5])*3+board[F6])
*3+board[F7])*3+board[F8];
if (Idx < 0)
Val3 -= Line3[-Idx];
else
Val3 += Line3[Idx];
//Line4
Val4 = 0;
Idx = ((((((board[A4]*3+board[B4])*3+board[C4])
*3+board[D4])*3+board[E4])*3+board[F4])
*3+board[G4])*3+board[H4];
if (Idx < 0)
Val4 -= Line4[-Idx];
else
Val4 += Line4[Idx];
Idx = ((((((board[A5]*3+board[B5])*3+board[C5])
*3+board[D5])*3+board[E5])*3+board[F5])
*3+board[G5])*3+board[H5];
if (Idx < 0)
Val4 -= Line4[-Idx];
else
Val4 += Line4[Idx];
Idx = ((((((board[D1]*3+board[D2])*3+board[D3])
*3+board[D4])*3+board[D5])*3+board[D6])
*3+board[D7])*3+board[D8];
if (Idx < 0)
Val4 -= Line4[-Idx];
else
Val4 += Line4[Idx];
Idx = ((((((board[E1]*3+board[E2])*3+board[E3])
*3+board[E4])*3+board[E5])*3+board[E6])
*3+board[E7])*3+board[E8];
if (Idx < 0)
Val4 -= Line4[-Idx];
else
Val4 += Line4[Idx];
//Diag4
Val5 = 0;
Idx = ((board[A4]*3+board[B3])*3+board[C2])
*3+board[D1];
if (Idx < 0)
Val5 -= Diag4[-Idx];
else
Val5 += Diag4[Idx];
Idx = ((board[E1]*3+board[F2])*3+board[G3])
*3+board[H4];
if (Idx < 0)
Val5 -= Diag4[-Idx];
else
Val5 += Diag4[Idx];
Idx = ((board[A5]*3+board[B6])*3+board[C7])
*3+board[D8];
if (Idx < 0)
Val5 -= Diag4[-Idx];
else
Val5 += Diag4[Idx];
Idx = ((board[E8]*3+board[F7])*3+board[G6])
*3+board[H5];
if (Idx < 0)
Val5 -= Diag4[-Idx];
else
Val5 += Diag4[Idx];
//Diag5
Val6 = 0;
Idx = (((board[A5]*3+board[B4])*3+board[C3])
*3+board[D2])*3+board[E1];
if (Idx < 0)
Val6 -= Diag5[-Idx];
else
Val6 += Diag5[Idx];
Idx = (((board[D1]*3+board[E2])*3+board[F3])
*3+board[G4])*3+board[H5];
if (Idx < 0)
Val6 -= Diag5[-Idx];
else
Val6 += Diag5[Idx];
Idx = (((board[A4]*3+board[B5])*3+board[C6])
*3+board[D7])*3+board[E8];
if (Idx < 0)
Val6 -= Diag5[-Idx];
else
Val6 += Diag5[Idx];
Idx = (((board[D8]*3+board[E7])*3+board[F6])
*3+board[G5])*3+board[H4];
if (Idx < 0)
Val6 -= Diag5[-Idx];
else
Val6 += Diag5[Idx];
//Diag6
Val7 = 0;
Idx = ((((board[A6]*3+board[B5])*3+board[C4])
*3+board[D3])*3+board[E2])*3+board[F1];
if (Idx < 0)
Val7 -= Diag6[-Idx];
else
Val7 += Diag6[Idx];
Idx = ((((board[C1]*3+board[D2])*3+board[E3])
*3+board[F4])*3+board[G5])*3+board[H6];
if (Idx < 0)
Val7 -= Diag6[-Idx];
else
Val7 += Diag6[Idx];
Idx = ((((board[A3]*3+board[B4])*3+board[C5])
*3+board[D6])*3+board[E7])*3+board[F8];
if (Idx < 0)
Val7 -= Diag6[-Idx];
else
Val7 += Diag6[Idx];
Idx = ((((board[C8]*3+board[D7])*3+board[E6])
*3+board[F5])*3+board[G4])*3+board[H3];
if (Idx < 0)
Val7 -= Diag6[-Idx];
else
Val7 += Diag6[Idx];
//Diag7
Val8= 0;
Idx = (((((board[A7]*3+board[B6])*3+board[C5])
*3+board[D4])*3+board[E3])*3+board[F2])
*3+board[G1];
if (Idx < 0)
Val8 -= Diag7[-Idx];
else
Val8 += Diag7[Idx];
Idx = (((((board[B1]*3+board[C2])*3+board[D3])
*3+board[E4])*3+board[F5])*3+board[G6])
*3+board[H7];
if (Idx < 0)
Val8 -= Diag7[-Idx];
else
Val8 += Diag7[Idx];
Idx = (((((board[A2]*3+board[B3])*3+board[C4])
*3+board[D5])*3+board[E6])*3+board[F7])
*3+board[G8];
if (Idx < 0)
Val8 -= Diag7[-Idx];
else
Val8 += Diag7[Idx];
Idx = (((((board[B8]*3+board[C7])*3+board[D6])
*3+board[E5])*3+board[F4])*3+board[G3])
*3+board[H2];
if (Idx < 0)
Val8 -= Diag7[-Idx];
else
Val8 += Diag7[Idx];
//Diag8
Val9 = 0;
Idx = ((((((board[A1]*3+board[B2])*3+board[C3])
*3+board[D4])*3+board[E5])*3+board[F6])
*3+board[G7])*3+board[H8];
if (Idx < 0)
Val9 -= Diag8[-Idx];
else
Val9 += Diag8[Idx];
Idx = ((((((board[A8]*3+board[B7])*3+board[C6])
*3+board[D5])*3+board[E4])*3+board[F3])
*3+board[G2])*3+board[H1];
if (Idx < 0)
Val9 -= Diag8[-Idx];
else
Val9 += Diag8[Idx];
//Edge8
Val0 = 0;
Idx = ((((((board[A1]*3+board[B1])*3+board[C1])
*3+board[D1])*3+board[A2])*3+board[B2])
*3+board[C2])*3+board[D2];
if (Idx < 0)
Val0 -= Edge8[-Idx];
else
Val0 += Edge8[Idx];
Idx = ((((((board[A1]*3+board[A2])*3+board[A3])
*3+board[A4])*3+board[B1])*3+board[B2])
*3+board[B3])*3+board[B4];
if (Idx < 0)
Val0 -= Edge8[-Idx];
else
Val0 += Edge8[Idx];
Idx = ((((((board[H1]*3+board[G1])*3+board[F1])
*3+board[E1])*3+board[H2])*3+board[G2])
*3+board[F2])*3+board[E2];
if (Idx < 0)
Val0 -= Edge8[-Idx];
else
Val0 += Edge8[Idx];
Idx = ((((((board[H1]*3+board[H2])*3+board[H3])
*3+board[H4])*3+board[G1])*3+board[G2])
*3+board[G3])*3+board[G4];
if (Idx < 0)
Val0 -= Edge8[-Idx];
else
Val0 += Edge8[Idx];
Idx = ((((((board[A8]*3+board[B8])*3+board[C8])
*3+board[D8])*3+board[A7])*3+board[B7])
*3+board[C7])*3+board[D7];
if (Idx < 0)
Val0 -= Edge8[-Idx];
else
Val0 += Edge8[Idx];
Idx = ((((((board[A8]*3+board[A7])*3+board[A6])
*3+board[A5])*3+board[B8])*3+board[B7])
*3+board[B6])*3+board[B5];
if (Idx < 0)
Val0 -= Edge8[-Idx];
else
Val0 += Edge8[Idx];
Idx = ((((((board[H8]*3+board[G8])*3+board[F8])
*3+board[E8])*3+board[H7])*3+board[G7])
*3+board[F7])*3+board[E7];
if (Idx < 0)
Val0 -= Edge8[-Idx];
else
Val0 += Edge8[Idx];
Idx = ((((((board[H8]*3+board[H7])*3+board[H6])
*3+board[H5])*3+board[G8])*3+board[G7])
*3+board[G6])*3+board[G5];
if (Idx < 0)
Val0 -= Edge8[-Idx];
else
Val0 += Edge8[Idx];
//空きマスの数によって、隅周辺の評価値を調整する。
Val = 0;
//if (board[A1] == BLACK)
// Val -= empties*2;
if (board[A1] == EMPTY && board[B2] == BLACK)
Val += empties*2;
//if (board[A1] == WHITE)
// Val += empties*2;
if (board[A1] == EMPTY && board[B2] == WHITE)
Val -= empties*2;
//if (board[H1] == BLACK)
// Val -= empties*2;
if (board[H1] == EMPTY && board[G2] == BLACK)
Val += empties*2;
//if (board[H1] == WHITE)
// Val += empties*2;
if (board[H1] == EMPTY && board[G2] == WHITE)
Val -= empties*2;
//if (board[A8] == BLACK)
// Val -= empties*2;
if (board[A8] == EMPTY && board[B7] == BLACK)
Val += empties*2;
//if (board[A8] == WHITE)
// Val += empties*2;
if (board[A8] == EMPTY && board[B7] == WHITE)
Val -= empties*2;
//if (board[H8] == BLACK)
// Val -= empties;
if (board[H8] == EMPTY && board[G7] == BLACK)
Val += empties;
//if (board[H8] == WHITE)
// Val += empties;
if (board[H8] == EMPTY && board[G7] == WHITE)
Val -= empties;
//評価値を石差の近似値に変換する。
var ev:int = (int)((Val1 + Val2 + Val3 + Val4 + Val5 + Val6 + Val7 + Val8 + Val9 + Val0 + Val) / 10);
if (ev > 50) ev = 50 + (int)((ev - 50) / 10);
//評価値を戻す
return (color == BLACK ? -ev : ev);
}
}