La classe "TicTacToe.hx" :

import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.utils.Timer;

class TicTacToe extends Sprite
{
    private var textFieldText : TextField = new TextField();
    private var grille : Sprite = new Sprite();
    private var panneaux : Sprite = new Sprite();
    private var panneauxText : Array<Dynamic> = ["Cliquez pour commencer", "Vous gagnez cliquer pour rejouer", "L'ordi gagne cliquer pour rejouer", "Match nul cliquer pour rejouer"];
   
    // variables
    private var J : Int = 1;
    private var T : Int = 160;
    private var C : Int = 3;
    private var P : Int = 0;
   
    // tableaux
    private var stock : Array<Dynamic> = [];
    private var valid : Array<Dynamic> = [];
    private var libre : Array<Dynamic> = [];
   
    public function new()
    {
            super();
            this.addEventListener( Event.ADDED_TO_STAGE, addedToStageHandler );
    }
   
    private function addedToStageHandler(e : Event) : Void
    {
            this.removeEventListener( Event.ADDED_TO_STAGE, addedToStageHandler );
           
            panneaux.graphics.beginFill(0x000000, 0.7);
            panneaux.graphics.drawRect(0, 0, 160 * 3, 160 * 3);
            panneaux.graphics.endFill();
           
            var textField : TextField = new TextField();
            //textField.border = true;
            var format : TextFormat = new TextFormat();
            format.font = "Verdana";
            format.color = 0xFFFFFF;
            format.size = 30;
            format.align = TextFormatAlign.CENTER;
            textField.defaultTextFormat = format;
           
            textField.selectable = false;
            textField.autoSize = TextFieldAutoSize.LEFT;
            textField.text = "Tic Tac Toe";
            var _height : Float = textField.height;
            textField.autoSize = TextFieldAutoSize.NONE;
            textField.width = 160 * 3;
            textField.height = _height;
            textField.y = 160 * 3 / 2 - textField.height - 10;
            panneaux.addChild(textField);
           
            //textFieldText.border = true;
            format.size = 20;
            textFieldText.defaultTextFormat = format;
           
            textFieldText.selectable = false;
            textFieldText.autoSize = TextFieldAutoSize.LEFT;
            textFieldText.text = panneauxText[0];
            _height = textFieldText.height;
            textFieldText.autoSize = TextFieldAutoSize.NONE;
            textFieldText.width = 160 * 3;
            textFieldText.height = _height;
            textFieldText.y = 160 * 3 / 2 + 10;
            panneaux.addChild(textFieldText);
           
            this.addChild(panneaux);
           
            grille.graphics.beginFill(0x000000);
            grille.graphics.drawRect(0, 0, 160 * 3, 160 * 3);
            grille.graphics.endFill();
            grille.graphics.beginFill(0x7a851a);
            grille.graphics.drawRect(0, 160 - 1, 160 * 3, 2);
            grille.graphics.endFill();
            grille.graphics.beginFill(0x7a851a);
            grille.graphics.drawRect(0, 160 * 2 - 1, 160 * 3, 2);
            grille.graphics.endFill();
            grille.graphics.beginFill(0x7a851a);
            grille.graphics.drawRect(160 - 1, 0, 2, 160 * 3);
            grille.graphics.endFill();
            grille.graphics.beginFill(0x7a851a);
            grille.graphics.drawRect(160 * 2 - 1, 0, 2, 160 * 3);
            grille.graphics.endFill();
           
            panneaux.addEventListener(MouseEvent.CLICK, init);
            panneaux.buttonMode = true;
    }
   
    private function createTileO() : Sprite
    {
            var tileO : Sprite = new Sprite();
            tileO.graphics.beginFill(0x009966);
            tileO.graphics.drawRect(0, 0, 160, 160);
            tileO.graphics.endFill();
            tileO.graphics.beginFill(0x0000cc);
            tileO.graphics.drawCircle(160 / 2, 160 / 2, 160 / 2 - 20);
            tileO.graphics.endFill();
            tileO.graphics.beginFill(0x009966);
            tileO.graphics.drawCircle(160 / 2, 160 / 2, 160 / 2 - 20 * 2);
            tileO.graphics.endFill();
            return tileO;
    }
   
    private function createTileX() : Sprite
    {
            var tileX : Sprite = new Sprite();
            tileX.graphics.beginFill(0x009966);
            tileX.graphics.drawRect(0, 0, 160, 160);
            tileX.graphics.endFill();
            var sprite : Sprite = new Sprite();
            sprite.graphics.beginFill(0xff0000);
            sprite.graphics.drawRoundRect(-(160 - 20 * 2) / 2, -10, 160 - 20 * 2, 20, 10);
            sprite.graphics.endFill();
            sprite.graphics.beginFill(0xff0000);
            sprite.graphics.drawRoundRect(-10, -(160 - 20 * 2) / 2, 20, 160 - 20 * 2, 10);
            sprite.graphics.endFill();
            sprite.rotation = 45;
            sprite.x = sprite.y = 160 / 2;
            tileX.addChild(sprite);
            return tileX;
    }
   
    // initialisation du jeu
    private function init(e : MouseEvent) : Void
    {
            J = 1;
            while (numChildren > 0)
            {
                    removeChildAt(0);
            }
            grille.addEventListener(MouseEvent.CLICK, remplir);
            grille.buttonMode = true;
            addChild(grille);
            stock = [0, 0, 0, 0, 0, 0, 0, 0, 0];
            valid = [[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6]];
            libre = [0, 1, 2, 3, 4, 5, 6, 7, 8];
    }
   
    // quel joueur joue
    private function remplir(e : Event) : Void
    {
            if (J == 1 && stock[P = Std.int(mouseX / T) + Std.int(mouseY / T) * C] == 0)
            {
                    remplirCase(createTileO());
                    latenceAI();
                    return;
            }
            if (J == 2)
            {
                    remplirCase(createTileX());
            }
    }
   
    // remplir la case du joueur
    private function remplirCase(b : Sprite) : Void
    {
            b.x = Std.int(P % C) * T;
            b.y = Std.int(P / C) * T;
            b.mouseEnabled = false;
            addChild(b);
            stock[P] = J;
            libre.splice(Lambda.indexOf(libre, P), 1);
            checkGagne();
    }
   
    // vérifie si un joueur gagne
    private function checkGagne() : Void
    {
            var fields = Reflect.fields(valid);
            var c:Array<Dynamic>;
            for (field in fields)
            {
                    c = Reflect.getProperty(valid, field);
                   
                    var w : Bool = true;
                   
                    var fields2 = Reflect.fields(c);
                    var i:Int;
                    for (field2 in fields2)
                    {
                            i = Reflect.getProperty(c, field2);
                           
                            w = w && stock[i] == J;
                    }
                    if (w)
                    {
                            nettoyage(J);
                            return;
                    }
            }
            if (libre.length == 0)
            {
                    nettoyage(3);
                    return;
            }
            (J == 1) ? J = 2 : J = 1;
    }
   
    private function nettoyage(f : Int) : Void
    {
            grille.removeEventListener(MouseEvent.CLICK, remplir);
            addChild(panneaux);
            textFieldText.text = panneauxText[f];
    }
   
    // temps de latence avant réponse de l'ordi
    private function latenceAI() : Void
    {
            grille.removeEventListener(MouseEvent.CLICK, remplir);
            var timer : Timer = new Timer(500, 1);
            timer.addEventListener( TimerEvent.TIMER_COMPLETE, choisiCase );
            timer.start();
    }
   
    // l'ordi choisi une case
    private function choisiCase(e : TimerEvent) : Void
    {
            grille.addEventListener(MouseEvent.CLICK, remplir);
            var tab : Array<Dynamic> = stock.copy();
            var i : String;
            for (i in Reflect.fields(libre))
            {
                    if (verifieCase(tab, 2, Reflect.field(libre, i)))
                    {
                            return;
                    }
            }
            for (i in Reflect.fields(libre))
            {
                    if (verifieCase(tab, 1, Reflect.field(libre, i)))
                    {
                            return;
                    }
            }
            remplirOrdi(libre[Std.int(Math.random() * libre.length)]);
    }
   
    // l'ordi vérifie si la case est gagnante
    private function verifieCase(tab : Array<Dynamic>, id : Int, b : Int) : Bool
    {
            tab[b] = id;
           
            var fields = Reflect.fields(valid);
            var c:Array<Dynamic>;
            for (field in fields)
            {
                    c = Reflect.getProperty(valid, field);
                   
                    var w : Bool = true;
                   
                    var fields2 = Reflect.fields(c);
                    var i:Int;
                    for (field2 in fields2)
                    {
                            i = Reflect.getProperty(c, field2);
                           
                            w = w && tab[i] == id;
                    }
                    if (w)
                    {
                            remplirOrdi(b);
                            return true;
                    }
            }
            tab[b] = 0;
            return false;
    }
   
    // l'ordi joue son coup
    private function remplirOrdi(p : Int) : Void
    {
            P = p;
            remplir(null);
    }
}