Neural Network BlackJack Trainer
Dealer - No learn. stand on soft 17.
Player - learn.
if output >0.5 (hit), else (stand).
number of inputNeuron is 38(no biased one).
It's for input of my score(2~20) and dealer score(2~20).
number of hiddenNeuron is 6(5 + biased one).
number of outputNeuron is only one. It's for hit/stand.
/**
* Copyright greentec ( http://wonderfl.net/user/greentec )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/xOgx
*/
package {
import com.bit101.charts.LineChart;
import com.bit101.components.Label;
import com.bit101.components.PushButton;
import com.bit101.components.Style;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.utils.ByteArray;
import flash.display.Sprite;
public class FlashTest extends Sprite {
public var _backBitmap:Bitmap;
public var playerHand:Array = [];
public var dealerHand:Array = [];
public static const blackJack:int = 21;
public static const dealerStandPoint:int = 17;
public var cardArray:Array = ["SA", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S10", "SJ", "SQ", "SK",
"DA", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9", "D10", "DJ", "DQ", "DK",
"HA", "H2", "H3", "H4", "H5", "H6", "H7", "H8", "H9", "H10", "HJ", "HQ", "HK",
"CA", "C2", "C3", "C4", "C5", "C6", "C7", "C8", "C9", "C10", "CJ", "CQ", "CK"];
//public var originalCard:Array = [];
public var nowCard:Array;
public static const initHandNum:int = 2;
public var inputNeuronNum:int = 38;
public var hiddenNeuronNum:int = 5;
public var outputNeuronNum:int = 1;
public var inputLayer:Layer;
public var hiddenLayer:Layer;
public var outputLayer:Layer;
public var learnRate:Number = 0.25;
public var _alpha:Number = 0.9; //for momentum
public var beta:Number;
public var playerWinGameNum:int = 0;
public var totalGameNum:int = 0;
public var winPercentLabel:Label;
public var errorChart:LineChart;
public var lineShape:Shape;
public var cardShape:Shape;
public var spadeShape:Shape;
public var diamondShape:Shape;
public var heartShape:Shape;
public var cloverShape:Shape;
public var dealerNumberLabelArray:Array;
public var playerNumberLabelArray:Array;
public var cardNumberRed:ColorTransform;
public var cardNumberBlack:ColorTransform;
public var labelWhite:ColorTransform;
public var cardBitmap:Bitmap;
public var cardBitmapData:BitmapData;
public var mat:Matrix;
public var pauseButton:PushButton;
public var makeTurnButton:PushButton;
public var dealerStatusLabel:Label;
public var playerStatusLabel:Label;
public function FlashTest() {
// write as3 code here..
stage.scaleMode = "noScale";
var i:int;
labelWhite = new ColorTransform();
labelWhite.color = 0xCCCCCC;
//cardNumberLabel = new Label(this, 0, 0, "");
//cardNumberLabel.scaleX = cardNumberLabel.scaleY = 2;
cardNumberRed = new ColorTransform();
cardNumberRed.color = 0xa5091e;
cardNumberBlack = new ColorTransform();
cardNumberBlack.color = 0x000000;
_backBitmap = new Bitmap(new BitmapData(465, 465, false, 0x185e3a));
var goldRect:Shape = new Shape();
goldRect.graphics.lineStyle(1, 0xf7b519);
goldRect.graphics.drawRoundRect(20, 20, 465 - 40, 465 - 40, 20, 20);
goldRect.graphics.drawRoundRect(15, 15, 465 - 30, 465 - 30, 30, 30);
_backBitmap.bitmapData.draw(goldRect);
addChild(_backBitmap);
lineShape = new Shape();
addChild(lineShape);
var _label:Label = new Label(this, 30, 30, "Dealer");
_label.transform.colorTransform = labelWhite;
dealerStatusLabel = new Label(this, 100, 30, "");
dealerStatusLabel.transform.colorTransform = labelWhite;
_label = new Label(this, 30, 465 / 3 - 10, "Player");
_label.transform.colorTransform = labelWhite;
playerStatusLabel = new Label(this, 100, _label.y, "");
playerStatusLabel.transform.colorTransform = labelWhite;
cardShape = new Shape();
cardShape.graphics.lineStyle(1, 0);
cardShape.graphics.beginFill(0);
cardShape.graphics.drawRoundRect(0, 0, 70, 94, 15, 15);
cardShape.graphics.beginFill(0xffffff);
cardShape.graphics.drawRoundRect(0, 0, 68, 93, 15, 15);
//cardShape.y = 45;
//cardShape.x = 30;
//addChild(cardShape);
spadeShape = new Shape();
spadeShape.graphics.lineStyle(1, 0x404b51);
spadeShape.graphics.beginFill(0);
//spadeShape.graphics.moveTo(12, 0);
//spadeShape.graphics.lineTo(3, 18);
//spadeShape.graphics.lineTo(12, 18);
//spadeShape.graphics.lineTo(8, 24);
//spadeShape.graphics.lineTo(16, 24);
//spadeShape.graphics.lineTo(12, 18);
//spadeShape.graphics.lineTo(21, 18);
//spadeShape.graphics.lineTo(12, 0);
//spadeShape.graphics.endFill();
spadeShape.graphics.moveTo(12, 0);
spadeShape.graphics.lineTo(3, 16);
spadeShape.graphics.lineTo(8, 20);
spadeShape.graphics.lineTo(12, 16);
spadeShape.graphics.lineTo(10, 24);
spadeShape.graphics.lineTo(14, 24);
spadeShape.graphics.lineTo(12, 16);
spadeShape.graphics.lineTo(16, 20);
spadeShape.graphics.lineTo(21, 16);
spadeShape.graphics.lineTo(12, 0);
spadeShape.graphics.endFill();
//spadeShape.x = 30;
//spadeShape.y = 45;
//addChild(spadeShape);
diamondShape = new Shape();
diamondShape.graphics.lineStyle(1, 0xc24117);
diamondShape.graphics.beginFill(0xa5091e);
diamondShape.graphics.moveTo(12, 0);
diamondShape.graphics.lineTo(6, 12);
diamondShape.graphics.lineTo(12, 24);
diamondShape.graphics.lineTo(18, 12);
diamondShape.graphics.lineTo(12, 0);
diamondShape.graphics.endFill();
//diamondShape.x = 30;
//diamondShape.y = 45;
//addChild(diamondShape);
heartShape = new Shape();
heartShape.graphics.lineStyle(1, 0xc24117);
heartShape.graphics.beginFill(0xa5091e);
heartShape.graphics.moveTo(12, 24);
heartShape.graphics.lineTo(3, 8);
heartShape.graphics.lineTo(8, 4);
heartShape.graphics.lineTo(12, 8);
heartShape.graphics.lineTo(16, 4);
heartShape.graphics.lineTo(21, 8);
heartShape.graphics.lineTo(12, 24);
heartShape.graphics.endFill();
//heartShape.x = 30;
//heartShape.y = 45;
//addChild(heartShape);
cloverShape = new Shape();
cloverShape.graphics.lineStyle(1, 0x404b51);
cloverShape.graphics.beginFill(0);
cloverShape.graphics.drawCircle(12, 7, 4);
cloverShape.graphics.drawCircle(7, 14, 4);
cloverShape.graphics.drawCircle(17, 14, 4);
cloverShape.graphics.moveTo(12, 16);
cloverShape.graphics.lineTo(8, 24);
cloverShape.graphics.lineTo(16, 24);
cloverShape.graphics.lineTo(12, 16);
//cloverShape.x = 30;
//cloverShape.y = 45;
//addChild(cloverShape);
cardBitmapData = new BitmapData(300, 300, true, 0x00ffffff);
cardBitmap = new Bitmap(cardBitmapData);
addChild(cardBitmap);
errorChart = new LineChart(this, 30, 465 - 180);
errorChart.height = 150;
errorChart.data = [0];
errorChart.lineColor = 0xff00ff;
winPercentLabel = new Label(this, errorChart.x, errorChart.y - 20, "");
winPercentLabel.transform.colorTransform = labelWhite;
pauseButton = new PushButton(this, 465 - 100 - 40, 465 - 70, "Pause", onPause);
pauseButton.toggle = true;
makeTurnButton = new PushButton(this, pauseButton.x, pauseButton.y + pauseButton.height + 2, "Make Turn", onMakeTurn);
makeTurnButton.enabled = false;
dealerNumberLabelArray = [];
for (i = 0; i < 11; i += 1)
{
_label = new Label(this, 0, 0, "");
_label.x = 38 + i * 28;
_label.y = 52;
dealerNumberLabelArray.push(_label);
}
playerNumberLabelArray = [];
for (i = 0; i < 11; i += 1)
{
_label = new Label(this, 0, 0, "");
_label.x = 38 + i * 28;
_label.y = 167;
playerNumberLabelArray.push(_label);
}
initNeuron();
initWeight();
//initNewGame();
addEventListener(Event.ENTER_FRAME, onLoop);
}
private function onMakeTurn(e:Event):void
{
onLoop();
}
private function onPause(e:Event):void
{
if (pauseButton.selected == true)
{
if (hasEventListener(Event.ENTER_FRAME) == true)
{
removeEventListener(Event.ENTER_FRAME, onLoop);
pauseButton.label = "Resume";
makeTurnButton.enabled = true;
}
}
else
{
if (hasEventListener(Event.ENTER_FRAME) == false)
{
addEventListener(Event.ENTER_FRAME, onLoop);
pauseButton.label = "Pause";
makeTurnButton.enabled = false;
}
}
}
private function onLoop(e:Event=null):void
{
initNewGame();
doGame();
drawLine();
}
private function drawLine():void
{
var i:int, j:int;
//graphic update
var lineThick:Number;
var lineColor:uint;
lineShape.graphics.clear();
for (i = 0; i < inputNeuronNum; i += 1)
{
for (j = 0; j < hiddenNeuronNum; j += 1)
{
lineColor = inputLayer.neurons[i].w[j] >= 0 ? 0x2a80b9 : 0xa31605;
lineThick = Math.abs(inputLayer.neurons[i].w[j]);
lineThick = lineThick/10 > 3 ? 3 : ( lineThick < 0.1 ? 0.1 : lineThick/10 );
lineShape.graphics.lineStyle(lineThick, lineColor);
lineShape.graphics.moveTo(inputLayer.neurons[i].x, inputLayer.neurons[i].y);
lineShape.graphics.lineTo(hiddenLayer.neurons[j].x, hiddenLayer.neurons[j].y);
}
}
for (i = 0; i < hiddenNeuronNum + 1; i += 1)
{
for (j = 0; j < outputNeuronNum; j += 1)
{
lineColor = hiddenLayer.neurons[i].w[j] >= 0 ? 0x2a80b9 : 0xa31605;
lineThick = Math.abs(hiddenLayer.neurons[i].w[j]);
lineThick = lineThick/10 > 3 ? 3 : ( lineThick < 0.1 ? 0.1 : lineThick/10 );
lineShape.graphics.lineStyle(lineThick, lineColor);
lineShape.graphics.moveTo(hiddenLayer.neurons[i].x, hiddenLayer.neurons[i].y);
lineShape.graphics.lineTo(outputLayer.neurons[j].x, outputLayer.neurons[j].y);
}
}
}
private function doGame():void
{
var playerWin:Boolean = false;
var dealerWin:Boolean = false;
var playerLose:Boolean = false;
var dealerLose:Boolean = false;
var gamedraw:Boolean = false;
var gameEnd:Boolean = false;
var turnCount:int = 0;
var playerPoint:Array = [];
var dealerPoint:Array = [];
var playerPointMax:int;
var dealerPointMax:int;
var playerPosition:String = "";
var dealerPosition:String = "";
var playRecord:Array = [];
var oneTurnRecord:Array = [];
//var playerInputArray:Array;
var i:int;
var j:int;
var k:int;
var str:String;
var len:int;
var end:int;
var sumError:Number = 0;
while (gameEnd == false && playerWin == false && dealerWin == false && playerLose == false && dealerLose == false && gamedraw == false) //until whoever win or lose
{
turnCount += 1;
//dealer Turn
//Point calc.
dealerPoint = [0];
dealerPointMax = -1;
for (i = 0; i < dealerHand.length; i += 1)
{
str = dealerHand[i].substr(1, dealerHand[i].length - 1);
if (str == "J" || str == "Q" || str == "K")
{
for (j = 0; j < dealerPoint.length; j += 1)
{
dealerPoint[j] += 10;
}
}
else if (str == "A")
{
len = dealerPoint.length;
for (j = 0; j < len; j += 1)
{
dealerPoint[j] += 1; //first Ace +1
dealerPoint.push(clone(dealerPoint[j])); //get double.. for all number of cases
}
for (j = len; j < dealerPoint.length; j += 1)
{
dealerPoint[j] += 10; //Ace +10. finally adding 11
}
}
else
{
for (j = 0; j < dealerPoint.length; j += 1)
{
dealerPoint[j] += parseInt(str);
}
}
}
//game lose Judge
for (i = dealerPoint.length - 1; i > -1; i -= 1)
{
if (dealerPoint[i] > blackJack) //over 21 -> delete!
{
dealerPoint.splice(i, 1);
}
else if (dealerPoint[i] == blackJack)
{
dealerWin = true;
dealerStatusLabel.text = "WIN";
gameEnd = true;
dealerPosition = "stand";
break;
}
}
if (dealerPoint.length == 0) // no point -> all over 21 -> dealer lose.
{
dealerPointMax = -1;
dealerLose = true;
dealerStatusLabel.text = "LOSE";
gameEnd = true;
dealerPosition = "stand";
}
else if(gameEnd == false) //점수가 있으니까 hit-stand 판단
{
dealerPointMax = -1;
for (j = 0; j < dealerPoint.length; j += 1)
{
if (dealerPoint[j] > dealerPointMax)
{
dealerPointMax = dealerPoint[j];
}
}
if (dealerPointMax >= dealerStandPoint)
{
dealerPosition = "stand";
dealerStatusLabel.text = "STAND";
}
else
{
dealerPosition = "hit";
dealerStatusLabel.text = "HIT";
}
}
//player Turn - NN 계산, hit or stand 결정
//Point 계산
playerPoint = [0];
playerPointMax = -1;
for (i = 0; i < playerHand.length; i += 1)
{
str = playerHand[i].substr(1, playerHand[i].length - 1);
if (str == "J" || str == "Q" || str == "K")
{
for (j = 0; j < playerPoint.length; j += 1)
{
playerPoint[j] += 10;
}
}
else if (str == "A")
{
len = playerPoint.length;
for (j = 0; j < len; j += 1)
{
playerPoint[j] += 1; //1을 더한다.
playerPoint.push(clone(playerPoint[j])); //2배로 늘린다..
}
for (j = len; j < playerPoint.length; j += 1)
{
playerPoint[j] += 10; //10을 더한다. 결국 마지막으로 추가된 것들에는 11을 더하는 꼴
}
}
else
{
for (j = 0; j < playerPoint.length; j += 1)
{
playerPoint[j] += parseInt(str);
}
}
}
//game lose 판단
for (i = playerPoint.length - 1; i > -1; i -= 1)
{
if (playerPoint[i] > blackJack) //21을 넘으면 과감하게 다 지운다.
{
playerPoint.splice(i, 1);
}
else if (playerPoint[i] == blackJack)
{
playerWin = true;
playerStatusLabel.text = "WIN";
gameEnd = true;
playerPosition = "stand";
break;
}
}
if (playerPoint.length == 0) //점수가 아무 것도 안 남아있다면, 다 21을 넘었다는 뜻이므로 dealer는 패배 확정.
{
playerPointMax = -1;
playerLose = true;
playerStatusLabel.text = "LOSE";
playerPosition = "stand";
gameEnd = true;
}
else if(gameEnd == false) //점수가 있으니까 hit-stand 판단
{
playerPointMax = -1;
for (j = 0; j < playerPoint.length; j += 1) //여기도 플레이어 포인트 Max를 계산해 놓는다. 나중에 비교해서 계산.
{
if (playerPoint[j] > playerPointMax)
{
playerPointMax = playerPoint[j];
}
}
//input Layer
for (i = 0; i < inputNeuronNum; i += 1)
{
inputLayer.neurons[i].output = 0; //일단 0으로 초기화
}
for (i = 0; i < playerPoint.length; i += 1)
{
inputLayer.neurons[blackJack - playerPoint[i] - 1].output = 1; //블랙잭(21)과 현재 점수의 차이를 input으로. 1~19 -> 0~18
}
if (dealerPoint.length > 0)
{
for (i = 0; i < dealerPoint.length; i += 1)
{
inputLayer.neurons[18 + blackJack - dealerPoint[i] - 1].output = 1; //딜러 점수에는 19~37번 Neuron 배정
}
}
//hidden Layer
for (i = 0; i < hiddenNeuronNum; i += 1)
{
hiddenLayer.neurons[i].input = 0;
for (j = 0; j < inputNeuronNum; j += 1)
{
hiddenLayer.neurons[i].input += inputLayer.neurons[j].output * inputLayer.neurons[j].w[i];
}
hiddenLayer.neurons[i].output = sigmoid(hiddenLayer.neurons[i].input);
}
hiddenLayer.neurons[hiddenNeuronNum].output = 1;
//ouput Layer
for (i = 0; i < outputNeuronNum; i += 1)
{
outputLayer.neurons[i].input = 0;
for (j = 0; j < hiddenNeuronNum + 1; j += 1)
{
outputLayer.neurons[i].input += hiddenLayer.neurons[j].output * hiddenLayer.neurons[j].w[i];
}
outputLayer.neurons[i].output = sigmoid(outputLayer.neurons[i].input);
if (outputLayer.neurons[i].output > 0.5)
{
playerPosition = "hit";
playerStatusLabel.text = "HIT";
}
else
{
playerPosition = "stand";
playerStatusLabel.text = "STAND";
}
}
//save record. 카드를 내는 상황에서 점수를 저장
oneTurnRecord = [];
for (i = 0; i < inputNeuronNum; i += 1)
{
oneTurnRecord.push(inputLayer.neurons[i].output);
}
oneTurnRecord.push(outputLayer.neurons[0].output);
playRecord.push(oneTurnRecord);
}
//win - lose judge
if (dealerPosition == "stand" && playerPosition == "stand")
{
if (dealerPointMax > playerPointMax)
{
if (dealerLose == false)
{
dealerWin = true;
dealerStatusLabel.text = "WIN";
if (playerWin == false)
{
playerLose = true;
playerStatusLabel.text = "LOSE";
}
gameEnd = true;
}
else
{
playerStatusLabel.text = "LOSE";
gameEnd = true;
}
}
else if (dealerPointMax < playerPointMax)
{
if (playerLose == false)
{
playerWin = true;
playerStatusLabel.text = "WIN";
if (dealerWin == false)
{
dealerLose = true;
dealerStatusLabel.text = "LOSE";
}
gameEnd = true;
}
else
{
dealerStatusLabel.text = "LOSE";
gameEnd = true;
}
}
else
{
gamedraw = true;
gameEnd = true;
dealerStatusLabel.text = "DRAW";
playerStatusLabel.text = "DRAW";
}
}
if(gameEnd == false) //card get
{
if (dealerPosition == "hit")
{
str = getOneCard();
dealerHand.push(str);
drawCardBitmap(true, dealerHand.length - 1, str);
dealerStatusLabel.text = "HIT";
}
if (playerPosition == "hit")
{
str = getOneCard();
playerHand.push(str);
drawCardBitmap(false, playerHand.length - 1, str);
playerStatusLabel.text = "STAND";
}
}
//trace(dealerHand, playerHand);
//trace(dealerPoint, playerPoint);
//trace(dealerWin, dealerLose, playerWin, playerLose);
//trace(dealerPosition, playerPosition);
}
//player가 blackjack이 아니라도 busted가 아니고, dealer가 busted라면 player win
if (playerLose == false && dealerLose == true)
{
playerWin = true;
playerStatusLabel.text = "WIN";
dealerStatusLabel.text = "LOSE";
}
if (playerWin == true && dealerWin == true)
{
playerStatusLabel.text = "DRAW";
dealerStatusLabel.text = "DRAW";
}
//Evaluation & Back-propagation
if (playerWin == false)
{
for (k = 0; k < playRecord.length; k += 1)
{
end = playRecord[k].length - 1;
outputLayer.neurons[0].error = playRecord[k][end] > 0.5 ? 0 - playRecord[k][end] : 1 - playRecord[k][end]; //했던 행동과 반대로 이끌기
outputLayer.neurons[0].error *= (k + 1) / turnCount;
sumError += outputLayer.neurons[0].error * outputLayer.neurons[0].error;
outputLayer.neurons[0].nodeDelta = outputLayer.neurons[0].error * outputLayer.neurons[0].output * (1 - outputLayer.neurons[0].output);
for (i = 0; i < hiddenNeuronNum + 1; i += 1) // +1 for biased Neuron
{
hiddenLayer.neurons[i].nodeDelta = 0;
for (j = 0; j < outputNeuronNum; j += 1)
{
hiddenLayer.neurons[i].deltaW[j] = learnRate * hiddenLayer.neurons[i].output * outputLayer.neurons[j].nodeDelta + _alpha * hiddenLayer.neurons[i].deltaW[j];
hiddenLayer.neurons[i].w[j] += hiddenLayer.neurons[i].deltaW[j]; //weight update;
hiddenLayer.neurons[i].nodeDelta += outputLayer.neurons[j].nodeDelta * hiddenLayer.neurons[i].w[j]; //get hidden neuron's nodeDelta
}
hiddenLayer.neurons[i].nodeDelta *= hiddenLayer.neurons[i].output * (1 - hiddenLayer.neurons[i].output);
}
for (i = 0; i < inputNeuronNum; i += 1)
{
for (j = 0; j < hiddenNeuronNum; j += 1)
{
inputLayer.neurons[i].deltaW[j] = learnRate * inputLayer.neurons[i].output * hiddenLayer.neurons[j].nodeDelta + _alpha * inputLayer.neurons[i].deltaW[j];
inputLayer.neurons[i].w[j] += inputLayer.neurons[i].deltaW[j]; //weight update;
}
}
}
}
else //playerWin == true
{
for (k = 0; k < playRecord.length; k += 1)
{
end = playRecord[k].length - 1;
outputLayer.neurons[0].error = playRecord[k][end] > 0.5 ? 1 - playRecord[k][end] : 0 - playRecord[k][end]; //했던 행동으로 이끌기
outputLayer.neurons[0].error *= (k + 1) / turnCount;
sumError += outputLayer.neurons[0].error * outputLayer.neurons[0].error;
outputLayer.neurons[0].nodeDelta = outputLayer.neurons[0].error * outputLayer.neurons[0].output * (1 - outputLayer.neurons[0].output);
for (i = 0; i < hiddenNeuronNum + 1; i += 1) // +1 for biased Neuron
{
hiddenLayer.neurons[i].nodeDelta = 0;
for (j = 0; j < outputNeuronNum; j += 1)
{
hiddenLayer.neurons[i].deltaW[j] = learnRate * hiddenLayer.neurons[i].output * outputLayer.neurons[j].nodeDelta + _alpha * hiddenLayer.neurons[i].deltaW[j];
hiddenLayer.neurons[i].w[j] += hiddenLayer.neurons[i].deltaW[j]; //weight update;
hiddenLayer.neurons[i].nodeDelta += outputLayer.neurons[j].nodeDelta * hiddenLayer.neurons[i].w[j]; //get hidden neuron's nodeDelta
}
hiddenLayer.neurons[i].nodeDelta *= hiddenLayer.neurons[i].output * (1 - hiddenLayer.neurons[i].output);
}
for (i = 0; i < inputNeuronNum; i += 1)
{
for (j = 0; j < hiddenNeuronNum; j += 1)
{
inputLayer.neurons[i].deltaW[j] = learnRate * inputLayer.neurons[i].output * hiddenLayer.neurons[j].nodeDelta + _alpha * inputLayer.neurons[i].deltaW[j];
inputLayer.neurons[i].w[j] += inputLayer.neurons[i].deltaW[j]; //weight update;
}
}
}
}
//stats
totalGameNum += 1;
if (playerWin == true)
{
playerWinGameNum += 1;
}
//errorChart.data.push(sumError);
errorChart.data.push(playerWinGameNum / totalGameNum);
errorChart.draw();
winPercentLabel.text = String(totalGameNum) + " Games, " + String(playerWinGameNum) + " WIN. (win Rate : " + String(int(playerWinGameNum / totalGameNum * 10000) / 100) + "%)";
//trace(dealerHand, playerHand);
}
public function sigmoid(n:Number):Number
{
return 1 / (1 + 1 / Math.exp(n));
}
private function initNeuron():void
{
var neuron:Neuron;
var i:int;
inputLayer = new Layer();
for (i = 0; i < inputNeuronNum; i += 1)
{
neuron = new Neuron(hiddenNeuronNum);
inputLayer.neurons.push(neuron);
neuron.x = 465 / 2 + 30 ;
neuron.y = (465 - 80) / inputNeuronNum * i + 40;
addChild(neuron);
}
hiddenLayer = new Layer();
for (i = 0; i < hiddenNeuronNum; i += 1)
{
neuron = new Neuron(outputNeuronNum);
hiddenLayer.neurons.push(neuron);
neuron.x = 465 / 4 * 3;
neuron.y = (465 - 300) / (hiddenNeuronNum) * i + 150;
addChild(neuron);
}
neuron = new Neuron(outputNeuronNum); //biased One for hidden Layer
neuron.biased = true;
hiddenLayer.neurons.push(neuron);
neuron.x = 465 / 4 * 3;
neuron.y = (465 - 300) / (hiddenNeuronNum) * hiddenNeuronNum + 150;
addChild(neuron);
outputLayer = new Layer();
for (i = 0; i < outputNeuronNum; i += 1)
{
neuron = new Neuron(0);
outputLayer.neurons.push(neuron);
}
neuron.x = 465 - 30;
neuron.y = 465 / 2;
addChild(neuron);
beta = 0.7 * Math.pow(hiddenNeuronNum, (1 / inputNeuronNum));
}
private function initWeight():void
{
// Nguyen-Widrow Initialization - for all Input to Hidden w
var normHidden:Number;
var i:int;
var j:int;
normHidden = 0;
for (i = 0; i < hiddenNeuronNum; i += 1)
{
for (j = 0; j < inputNeuronNum; j += 1)
{
normHidden += inputLayer.neurons[j].w[i] * inputLayer.neurons[j].w[i];
}
normHidden = Math.sqrt(normHidden);
for (j = 0; j < inputNeuronNum; j += 1)
{
inputLayer.neurons[j].w[i] *= beta / normHidden;
}
}
}
private function initNewGame(e:Event=null):void
{
var str:String;
cardBitmapData.fillRect(cardBitmapData.rect, 0x00ffffff);
var _label:Label;
var i:int;
for (i = 0; i < 11; i += 1)
{
_label = dealerNumberLabelArray[i];
_label.text = "";
_label = playerNumberLabelArray[i];
_label.text = "";
}
nowCard = clone(cardArray);
playerHand = [];
dealerHand = [];
str = getOneCard();
playerHand.push(str);
drawCardBitmap(false, 0, str);
str = getOneCard();
playerHand.push(str);
drawCardBitmap(false, 1, str);
str = getOneCard();
dealerHand.push(str);
drawCardBitmap(true, 0, str);
str = getOneCard();
dealerHand.push(str);
drawCardBitmap(true, 1, str);
//trace(playerHand, dealerHand);
}
private function drawCardBitmap(isDealer:Boolean, index:int, str:String):void
{
var number:String = str.substr(1, str.length - 1);
var mark:String = str.substr(0, 1);
var label:Label;
//trace(str, mark, number, index)
mat = new Matrix();
if (isDealer == true)
{
mat.translate(30 + index * 28, 50);
label = dealerNumberLabelArray[index];
}
else
{
mat.translate(30 + index * 28, 165);
label = playerNumberLabelArray[index];
}
cardBitmapData.draw(cardShape, mat);
//mat.translate(8, 2);
label.text = number;
switch(mark)
{
case "S":
case "C":
//cardNumberLabel.transform.colorTransform = cardNumberBlack;
//cardBitmapData.draw(label, mat, cardNumberBlack); trace(label.text);
label.transform.colorTransform = cardNumberBlack;
break;
case "D":
case "H":
//cardNumberLabel.transform.colorTransform = cardNumberRed;
//cardBitmapData.draw(label, mat, cardNumberRed); trace(label.text);
label.transform.colorTransform = cardNumberRed;
break;
}
//cardBitmapData.draw(String(number), mat);
mat.translate(2, 22);
switch(mark)
{
case "S":
cardBitmapData.draw(spadeShape, mat);
break;
case "D":
cardBitmapData.draw(diamondShape, mat);
break;
case "H":
cardBitmapData.draw(heartShape, mat);
break;
case "C":
cardBitmapData.draw(cloverShape, mat);
break;
}
}
private function getOneCard():String
{
var arr:Array = printRandomNumber(nowCard.length, 1);
var str:String = nowCard[arr[0]];
nowCard.splice(arr[0], 1);
return str;
}
private function printRandomNumber(n:int, k:int) : Array
{
var original:Array=[];
var result:Array=[];
var i:int;
var randInt:int;
var temp:Object;
for(i=0;i<n;i+=1)
{
original.push(i);
}
for(i=0;i<k;i+=1)
{
randInt = Math.random()*(n-i) + i;
temp = original[i];
original[i] = original[randInt];
original[randInt] = temp;
result.push(original[i]);
}
return result;
}
public function clone(source:Object):*
{
var myBA:ByteArray = new ByteArray();
myBA.writeObject(source);
myBA.position = 0;
return(myBA.readObject());
}
}
}
Class
{
import flash.display.Shape;
/**
* ...
* @author ypc
*/
class Neuron extends Shape
{
public var w:Object;
public var deltaW:Object;
public var updateValue:Object;
public var prevGradient:Object;
public var input:Number;
public var output:Number;
public var error:Number;
public var nodeDelta:Number;
public var gradient:Object;
public var gradientChanged:Object;
public var biased:Boolean = false;
public function Neuron(n:int)
{
this.graphics.lineStyle(2, 0);
this.graphics.beginFill(0xffffff);
this.graphics.drawCircle(0, 0, 6);
this.graphics.endFill();
this.w = new Object();
this.deltaW = new Object();
this.updateValue = new Object();
this.prevGradient = new Object();
this.gradient = new Object();
this.gradientChanged = new Object();
if (n > 0)
{
var i:int;
for (i = 0; i < n; i += 1)
{
this.w[i] = Math.random() * 2 - 1;
this.deltaW[i] = 0;
this.updateValue[i] = 0.01;
this.gradient[i] = 0;
this.prevGradient[i] = 0;
this.gradientChanged[i] = 0;
}
}
}
public function resetW(n:int):void
{
var i:int;
for (i = 0; i < n; i += 1)
{
this.w[i] = Math.random() * 2 - 1;
this.deltaW[i] = 0;
this.updateValue[i] = 0.01;
this.gradient[i] = 0;
this.prevGradient[i] = 0;
this.gradientChanged[i] = 0;
this.error = 0;
this.nodeDelta = 0;
}
}
}
}
Class
{
/**
* ...
* @author ypc
*/
class Layer
{
public var neurons:Array;
public function Layer()
{
this.neurons = [];
}
}
}