function createContext (name) {
     return {
         name:game_number + "_" + name,
         ready_promise:promise.defer(),
         my_gate:"",
         other_gate:"",
         my_shots:0,
         his_shots:0
     };
 };
function Game (game_number, base_path) {
    var start_promise = promise.defer();
    function createContext (name) {
        return {
            name:game_number + "_" + name,
            ready_promise:promise.defer(),
            my_gate:"",
            other_gate:"",
            my_shots:0,
            his_shots:0
        };
    };
    var playerAContext = this.playerAContext = createContext ("A");
    var playerBContext = this.playerBContext = createContext ("B");
    
    function Player (context) {
        var zk = new ZK ().init (zk_config);
        zk.on_connected().
            then ( // create my own gate node 
                function (zkk){
                    console.log ("player %s on_connected: zk=%j", context.name, zkk);
                    return zkk.create (base_path + context.name, "target", 0/*ZK.ZOO_SEQUENCE*/);
                }
            ).then ( // store the actual gate node path in the context and fire "I'm ready"
                function (actual_gate_path) {
                    console.log ("player %s created his gate at=%s", context.name, actual_gate_path);
                    context.my_gate = actual_gate_path;
                    context.ready_promise.resolve ();
                    return start_promise; 
                },
                function (error) {
                    if (error == ZK.ZNODEEXISTS) {
                        context.my_gate = base_path + context.name;
                        context.ready_promise.resolve ();
                        return start_promise; 
                    } else {
                        throw new Error (error);
                    }
                }
            ).then ( // game is on: shoot!
                function () {
                    Defend ();
                    Shoot ();
                }
            );
        
        var Shoot = function () {
            console.log ("====>player %s says: I made %d shots, he made %s shots", context.name, context.my_shots, context.his_shots);
            console.log ("player %s is about to attack", context.name);
            zk.create (context.other_gate + "/attack", "kick", ZK.ZOO_SEQUENCE | ZK.ZOO_EPHEMERAL).then (
                function (created_node) {
                    console.log ("player %s attacked with %s", context.name, created_node);
                    context.my_shots ++;
                    Shoot ();
                }
            )
        };
        
        var Defend = function () {
            zk.w_get_children (context.my_gate, 
                function (type, state, path) { //this is my defence watcher
                    console.log ("defense watcher triggered for player %s: type=%d, path=%s", context.name,type, path);
                    Defend ();
                }
            ).then (
                function (children) {// these are attacks against me; I have to stop them
                    if (!children || !children.length ) return;
                    var delete_promisses = [];
                    children.forEach (
                        function (child) {
                            var ch_path = context.my_gate+"/"+child;
                            console.log ("player %s is stopping attack %s", context.name, ch_path);
                            var prm = zk.delete_ (ch_path, -1);
                            delete_promisses.push (prm);
                            context.his_shots ++;
                        }
                    );
                    promise.all (delete_promisses).then (
                        function () { //all children where deleted
                            console.log ("player %s stopped %d attacks: %j", context.name, delete_promisses.length, children);
                        }
                    );
                }
            );
        };
        
    }; // end of Player
    
    var pA = Player (playerAContext);
    var pB = Player (playerBContext);
    promise.all ([playerAContext.ready_promise, playerBContext.ready_promise]).then (
        function () {
            playerAContext.other_gate = playerBContext.my_gate; 
            playerBContext.other_gate = playerAContext.my_gate;
            console.log ("------- GAME #%d is ON!--------", game_number);
            start_promise.resolve ();
        }
    );
    
};