example

by yurij.shaulov
нихрена не работает, лагает и тормозит по страшному!
♥0 | Line 840 | Modified 2014-09-11 06:27:31 | MIT License
play

ActionScript3 source code

/**
 * Copyright yurij.shaulov ( http://wonderfl.net/user/yurij.shaulov )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/1NCZ
 */

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 Main extends Sprite {

        //фон 

        public var _backBitmap:Bitmap;

        // список карт у игрока

        public var playerHand:Array = [];

        // список карт у дилера

        public var dealerHand:Array = [];

        // максимум для проигрыша

        public static const blackJack:int = 21;

        // точка остановки диллера (не будет брать карту если >=17)

        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; //для импульса

        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 mat:Matrix;

        

        public var cardBitmap:Bitmap;

        public var cardBitmapData:BitmapData;

        

        public var pauseButton:PushButton;

        public var makeTurnButton:PushButton;

        

        public var dealerStatusLabel:Label;

        public var playerStatusLabel:Label;

        

        public function Main() {



            stage.scaleMode = "noScale";

            

            stage.frameRate = 500;

            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, "Go", 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;

            // обновление графики

            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) //до тех пор, пока кто-нибдь не выиграл или не проиграл

            {

                turnCount += 1;

                

                //dealer ходит

                    //точка отсчёта

                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; //первый туз +1

                            dealerPoint.push(clone(dealerPoint[j])); //удвоить результат, для всех случаев

                        }

                        for (j = len; j < dealerPoint.length; j += 1)

                        {

                            dealerPoint[j] += 10; //туз +10. наконец, добавив 11

                        }

                    }

                    else

                    {

                        for (j = 0; j < dealerPoint.length; j += 1)

                        {

                            dealerPoint[j] += parseInt(str);

                        }

                    }

                }

                



                for (i = dealerPoint.length - 1; i > -1; i -= 1)

                {

                    if (dealerPoint[i] > blackJack) //больше 21 - дилер проиграл

                    {

                        dealerPoint.splice(i, 1);

                    }

                    else if (dealerPoint[i] == blackJack)

                    {

                        dealerWin = true;

                        dealerStatusLabel.text = "WIN";

                        gameEnd = true;

                        dealerPosition = "stand";

                        break;

                    }

                }

                

                if (dealerPoint.length == 0) // нет баллов, скорее всего дилер проиграл

                {

                    dealerPointMax = -1;

                    dealerLose = true;

                    dealerStatusLabel.text = "LOSE";

                    gameEnd = true;

                    dealerPosition = "stand";

                }

                else if(gameEnd == false) //нужно определить состояние 

                {

                    dealerPointMax = -1;

                    

                    for (j = 0; j < dealerPoint.length; j ++)

                    {

                        if (dealerPoint[j] > dealerPointMax)

                        {

                            dealerPointMax = dealerPoint[j];

                        }

                    }

                    

                    if (dealerPointMax >= dealerStandPoint)

                    {

                        dealerPosition = "stand";

                        dealerStatusLabel.text = "STAND";

                    }

                    else

                    {

                        dealerPosition = "hit";

                        dealerStatusLabel.text = "HIT";

                    }

                }

                    

                

                //игрок решает ходить или стоять

                    //точка расчёта

                playerPoint = [0];

                playerPointMax = -1;

                

                for (i = 0; i < playerHand.length; i ++)

                {

                    str = playerHand[i].substr(1, playerHand[i].length - 1);

                    if (str == "J" || str == "Q" || str == "K")

                    {

                        for (j = 0; j < playerPoint.length; j ++)

                        {

                            playerPoint[j] += 10;

                        }

                        

                    }

                    else if (str == "A")

                    {

                        len = playerPoint.length;

                        for (j = 0; j < len; j += 1)

                        {

                            playerPoint[j] += 1; //добавляем один

                            playerPoint.push(clone(playerPoint[j])); //Увеличивает в два раза.

                        }

                        for (j = len; j < playerPoint.length; j += 1)

                        {

                            playerPoint[j] += 10; //добавляем 10

                        }

                    }

                    else

                    {

                        for (j = 0; j < playerPoint.length; j += 1)

                        {

                            playerPoint[j] += parseInt(str);

                        }

                    }

                }

                

                //игра проиграна

                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) //если у игрока 0, то это ещё ничего не знчит, потомучто у диллера может превышать 21

                {

                    playerPointMax = -1;

                    playerLose = true;

                    playerStatusLabel.text = "LOSE";

                    playerPosition = "stand";

                    gameEnd = true;

                }

                else if(gameEnd == false) 

                {

                    

                    playerPointMax = -1;

                    

                    for (j = 0; j < playerPoint.length; j ++) //расчитываем максимальное число баллов играка сравнивая с предыдущим

                    {

                        if (playerPoint[j] > playerPointMax)

                        {

                            playerPointMax = playerPoint[j];

                        }

                    }

                    

                        //запускаим входной слой нейронов

                    for (i = 0; i < inputNeuronNum; i ++)

                    {

                        inputLayer.neurons[i].output = 0; // инициализируем в 0

                    }

                    

                    for (i = 0; i < playerPoint.length; i += 1)

                    {

                        inputLayer.neurons[blackJack - playerPoint[i] - 1].output = 1; //блэкджек (21) и оценка разности входа. 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

                        }

                    }

                    

                        //скрытый слой нейронов

                    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;

                    

                        //выходной слой

                    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";

                        }

                        

                        

                    }

                    

                    //сохраняем значения для последующей оценки подобных ситуаций

                    oneTurnRecord = [];

                    for (i = 0; i < inputNeuronNum; i += 1)

                    {

                        oneTurnRecord.push(inputLayer.neurons[i].output);

                    }

                    oneTurnRecord.push(outputLayer.neurons[0].output);

                    

                    playRecord.push(oneTurnRecord);

                    

                }

                

                

                

                

                //оцениваем кто выигра, а кто проиграл

                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) 

                {

                    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); //выводит состояния игроков

            }

            

            

            if (playerLose == false && dealerLose == true)

            {

                playerWin = true;

                playerStatusLabel.text = "WIN";

                dealerStatusLabel.text = "LOSE";

            }

            if (playerWin == true && dealerWin == true)

            {

                playerStatusLabel.text = "DRAW";

                dealerStatusLabel.text = "DRAW";

            }

            

            //Оценка эволюции

            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 За нейрон не находящийся под влиянием других

                    {

                        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]; //обновление веса

                            

                            hiddenLayer.neurons[i].nodeDelta += outputLayer.neurons[j].nodeDelta * hiddenLayer.neurons[i].w[j]; //перерасчитываем дельту скрытого нейрона

                        }

                        

                        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]; //обновляем вес;

                        }

                    }

                }

            }

            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 за нейрон без влияния

                    {

                        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]; 

                            

                            hiddenLayer.neurons[i].nodeDelta += outputLayer.neurons[j].nodeDelta * hiddenLayer.neurons[i].w[j]; 

                        }

                        

                        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]; 

                        }

                    }

                }

            }

            

            

            //состояния игр

            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); //нейрон без влияния для скрытого слоя

            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

        {

            // алгоритм Нгуен-Уидроу  инициализация- всех скрытых нейронов

            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;

    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

{

    class Layer 

    {

        public var neurons:Array;

        

        public function Layer() 

        {

            this.neurons = [];

        }

        

    }



}