Danil Eremeev avatar Danil Eremeev committed 644731c

Initial release

Comments (0)

Files changed (5)

+Сервер для игры алгоритмов в морской бой
+========================================
+
+Сделано когда то на NodeJs просто для развлекухи
+
+Эта вещь делалась в свободное от работы время (которого немного), и возможны некоторые "баги". 
+Поэтому, если возникнут какие то проблемы, со мной всегда можно связаться.
+
+О том как написать алгоритм:
+
+* Выбирай любой язык который нравится: js (node), php, perl, python
+* При первом запуске передается 1 параметр generate
+* Алгоритм должен сгенерировать кораблей на поле 10х10
+* Свободные клетки должны быть равны 0, корабли отмечаются 1
+* Корабли не могут быть на соседних клетках. Так же они не могут изгибаться и быть по диагонали.
+* Столбцы разделяем ,
+* Строки разделяем \\n
+* Количество кораблей: 4 однопалубных, 3 двухпалубных, 2 трехпалубных, 1 четырехпалубный
+* Сервер проверит количество и правильность расстановки кораблей и начнет бой.
+
+Все следующие запуски алгоритма будут с 2я параметрами:
+
+1. shot<br>
+2. filename = имя файла где сервером будет помещена следующая информация:
+
+- Поле 10x10 противника. где 2йкой обозначается попадание по палубе корабля противника. 3йкой - попадание в пустое место 
+- пустая строка<br>
+- Поле 10х10 сгенерированное этим алгоритмом с теми же обозначениями что выше - означающими удары противника по тебе.
+
+При получении этих параметров алгоритм должен рассчитать свой следующий удар, и вернуть x,y
+
+**Запуск**
+
+node server.js 1.js 2.js
+var fs = require('fs');
+var schemas=[];
+var 
+ schema="0,0,1,0,0,0,0,0,0,0\n";
+schema+="1,0,1,0,0,0,0,1,0,0\n";
+schema+="1,0,0,0,0,0,0,0,0,0\n";
+schema+="1,0,1,0,0,0,0,0,0,0\n";
+schema+="0,0,1,0,0,1,0,0,0,0\n";
+schema+="1,0,0,0,0,0,0,1,0,0\n";
+schema+="1,0,1,0,0,0,0,0,0,0\n";
+schema+="1,0,1,0,0,0,0,0,0,0\n";
+schema+="0,0,0,0,0,0,1,0,0,0\n";
+schema+="1,1,1,1,0,0,0,0,0,0";
+
+schemas.push(schema);
+
+
+if (process.argv.length==3 && process.argv[2]=="generate"){
+    console.log(schema);
+}
+else if (process.argv.length==4 && process.argv[2]=="shot"){
+    var inpFile=process.argv[3];
+    var inputStr=fs.readFileSync(__dirname+"/"+inpFile).toString();
+    
+    var arr=inputStr.split("\n",10);
+    //Generating 2dimensional array of opposite field
+    var field=[];
+    for (var i=0;i<10;i++){
+        field.push(arr[i].split(","));
+    }
+    var avail=[];
+    for (var y=0;y<10;y++){
+        for (var x=0;x<10;x++){
+            if (field[x][y]==0) avail.push([x,y]);
+        }
+    }
+    var next= Math.floor(Math.random() * (avail.length-1));
+    console.log(avail[next][0]+","+avail[next][1]);
+    //console.log("3,0");
+}
+var fs = require('fs');
+var schemas=[];
+var 
+ schema="0,0,1,0,0,0,0,0,0,0\n";
+schema+="1,0,1,0,0,0,0,1,0,0\n";
+schema+="1,0,0,0,0,0,0,0,0,0\n";
+schema+="1,0,1,0,0,0,0,0,0,0\n";
+schema+="0,0,1,0,0,1,0,0,0,0\n";
+schema+="1,0,0,0,0,0,0,1,0,0\n";
+schema+="1,0,1,0,0,0,0,0,0,0\n";
+schema+="1,0,1,0,0,0,0,0,0,0\n";
+schema+="0,0,0,0,0,0,1,0,0,0\n";
+schema+="1,1,1,1,0,0,0,0,0,0";
+
+schemas.push(schema);
+
+
+if (process.argv.length==3 && process.argv[2]=="generate"){
+    console.log(schema);
+}
+else if (process.argv.length==4 && process.argv[2]=="shot"){
+    var inpFile=process.argv[3];
+    var inputStr=fs.readFileSync(__dirname+"/"+inpFile).toString();
+    
+    var arr=inputStr.split("\n",10);
+    //Generating 2dimensional array of opposite field
+    var field=[];
+    for (var i=0;i<10;i++){
+        field.push(arr[i].split(","));
+    }
+    var avail=[];
+    for (var y=0;y<10;y++){
+        for (var x=0;x<10;x++){
+            if (field[x][y]==0) avail.push([x,y]);
+        }
+    }
+    var next= Math.floor(Math.random() * (avail.length-1));
+    console.log(avail[next][0]+","+avail[next][1]);
+    //console.log("3,0");
+}
+3,3,0,3,3,3,3,3,3,3
+2,3,2,3,3,3,3,2,3,3
+2,3,3,3,3,3,3,3,3,0
+2,0,2,3,3,3,0,3,3,3
+3,3,2,3,3,2,3,0,3,0
+2,3,3,3,3,3,3,2,3,3
+2,3,2,3,0,3,3,3,3,3
+2,3,2,3,3,3,3,3,0,3
+3,3,3,3,3,3,2,3,3,0
+2,2,2,2,3,3,3,3,3,0
+
+3,3,2,3,3,3,3,3,3,3
+2,3,1,3,3,0,3,2,3,3
+2,3,3,3,3,3,3,3,3,3
+2,3,2,3,3,3,3,3,0,3
+3,3,2,3,3,1,3,3,3,3
+2,3,0,3,3,3,3,2,3,0
+2,3,2,3,3,3,3,3,3,3
+2,3,2,3,3,3,3,3,0,3
+3,3,0,3,3,3,2,3,3,3
+2,2,2,2,0,3,3,3,3,0
+var spawn = require('child_process').spawn;
+var fs = require('fs');
+//var Client = require('mysql').Client;
+
+function player(file,name,logObj){
+    this.name=name;
+    var field=[];
+    var ships=[];
+    var shipsC=[0,4,3,2,1]; //0 0 палубных. 4 однопалубных.....
+    this.generateField=function(callback){
+        var me=this;
+        var p=run(["generate"]);
+        var buf="";
+        p.stdout.setEncoding('utf8');
+        p.stdout.on('data',function(data){  //loading ship data
+            buf+=data.toString();
+        });
+        p.on('exit', function (code) {      //check ship placements
+            try{
+                logObj.push({type:"log",proc:me.name,val:buf});
+                var arr=buf.split("\n");       //loading desk.
+                //if (arr.length!=10) throw Error("Wrong rows count");
+                for (var i=0;i<10;i++){
+                    field[i]=arr[i].split(",");
+                    if (field[i].length!=10) throw Error("Wrong cols count");
+                }                               //from here checking placement
+                for(var y=0;y<10;y++){
+                    for (var x=0;x<10;x++){
+                        var ship=findShip(x,y,null);
+                        if (ship!=null){
+                            shipsC[ship.length]--;
+                            ships.push(ship);
+                        }
+                    }
+                } 
+                for (var y=0;y<10;y++) //normalize field after loading ships
+                    for(var x=0;x<10;x++)
+                        if (field[x][y]==5) field[x][y]=1;
+                for (var i=0;i<shipsC.length;i++){//Checking ships count
+                    if (shipsC[i]!=0) throw Error("Wrong ships count");
+                }
+            }catch(e){
+                callback(me,buf,"error");
+                return;
+            }
+            callback(me,buf);
+        });
+    };
+    //5- ship was seing
+    function findShip(x,y,ship,throwErr){
+        throwErr=(throwErr==null)?false:throwErr;
+        if (x<0 || y<0 || x>=10 || y>=10) return ship;
+        if (field[x][y]==1){
+            if (throwErr) throw Error("Wrong ship placement");
+            field[x][y]=5;
+            
+            if (ship==null) var ship = [[x,y]];
+            else ship.push([x,y]);
+            
+            findShip(x-1,y,ship);
+            findShip(x,y-1,ship);
+            findShip(x+1,y,ship);
+            findShip(x,y+1,ship);
+            findShip(x+1,y+1,ship,true);
+            findShip(x-1,y+1,ship,true);
+            findShip(x+1,y-1,ship,true);
+            return ship;
+        }
+        return ship;
+    }
+    
+    function run(args){
+        var ext=file.split(".");
+        ext=ext[ext.length-1];
+        var prog="";
+        switch(ext){
+            case "js": prog="node"; break;
+            case "php": prog="node"; break;
+            case "pl": prog="perl"; break;
+            case "py": prog="python"; break;
+        };
+        return spawn(prog,["./algos/"+file].concat(args));
+    }
+    
+    function hasShip(x,y){
+        for (var i=0;i<ships.length;i++){
+            for (var j=0;j<ships[i].length;j++){
+                if (ships[i][j][0]==x && ships[i][j][1]==y)
+                    return ships[i].length;
+            }
+        }
+        return false;
+    }
+      
+    function imLoose(){
+        for (var i=0;i<ships.length;i++)
+            for (var j=0;j<ships[i].length;j++)
+                if ( field[ships[i][j][0]][ships[i][j][1]]==1) return false;
+        return true;
+    }  
+    this.shot=function(opponent,result){
+        var myfield=getArrString(field);
+        var opfield=getArrString(opponent.fieldForOpponent());
+        fs.writeFileSync("data.txt",opfield+"\n\n"+myfield);
+        var p=run(["shot","../data.txt"]);
+        var buf="";
+        p.stdout.on('data',function(data){ 
+            buf+=data.toString();
+        });
+        p.on('exit',function(code){
+            logObj.push({type:"log", proc:name, val:buf});
+            var arr=buf.split(",",2);
+            if (arr.length!=2) throw Error("Wrong return");
+            result(arr[0],arr[1]);
+        });
+    }
+    this.boom=function(x,y){//2- hit paluba. 3- miss
+        if (x<0 || y<0 || x>=10 || y>=10) throw Error("Coords Error");
+        if (field[x][y]==1) {field[x][y]=2; return imLoose()?"loose":"hit";}
+        field[x][y]=3;
+        return imLoose()?"loose":"miss";
+    }
+
+    this.fieldForOpponent=function(){
+        var out=[];
+        for (var y=0;y<10;y++) {//removing ships
+            out.push([]);
+            for(var x=0;x<10;x++){
+                out[y].push(field[y][x]);
+                if (out[y][x]==1) out[y][x]=0;
+            }
+        }
+        return out;
+    }
+
+    function getArrString(arr){
+        var sarr="";
+        for (var y=0;y<10;y++){
+            for(var x=0;x<10;x++){
+                sarr+=arr[y][x]+",";
+            }
+            sarr=sarr.substr(0,sarr.length-1);
+            sarr+="\n";
+        }
+        sarr=sarr.substr(0,sarr.length-1);
+        return sarr;
+    }
+
+};
+var procss=[];
+var log=[];
+
+var name1=process.argv[2].split(".")[0];//Get only algorithm id
+var name2=process.argv[3].split(".")[0];
+
+try{ 
+    (new player(process.argv[2],name1,log)).generateField(doneGenerating); 
+}catch(e){
+    log.push({type:"log",proc:name1,val:e.toString()});
+    whoIsWinner(name2);
+}
+
+try{ 
+    (new player(process.argv[3],name2,log)).generateField(doneGenerating); 
+}catch(e){
+    log.push({type:"log",proc:name2,val:e.toString()});
+    whoIsWinner(name1);
+}
+var errProc=null;
+function doneGenerating(proc,outForLog,err){
+    if (err) errProc=proc;
+    procss.push(proc);
+    log.push({type:"field",proc:proc.name,val:outForLog});
+    if (procss.length==2) {
+        if (errProc){ 
+            var win;
+            for (var i=0;i<2;i++){
+                if (procss[i].name!=errProc.name) win=procss[i].name;
+            }
+            whoIsWinner(win);
+            }
+        else game(procss[0],procss[1]);
+    }
+}
+
+function game(proc,opponent){
+    try{
+        proc.shot(opponent,function(x,y){
+            log.push({type:"shot",proc:proc.name,val:[x,y]});
+            var ret=opponent.boom(Number(x),Number(y));
+            var procNext,opNext;
+            switch(ret){
+                case "miss": procNext=opponent; opNext=proc; break;
+                case "loose":
+                    whoIsWinner(proc.name);
+                    return;
+                case "hit": procNext=proc; opNext=opponent; break;
+            }
+            process.nextTick(function(){game(procNext,opNext);});
+        });
+    }catch( e){
+        log.push({type:"log",proc:proc.name,val:e.toString()});
+        whoIsWinner(opponent);
+    }
+}
+
+function whoIsWinner(winnerProc){
+    if (process.argv.length!=5) { // If we havn't game id in params -> 
+        console.dir(log);         //we just working in console
+        console.log("WINNER IS:"+winnerProc);
+        process.exit(0);
+    }
+    var client = new Client();
+    client.user = "";
+    client.password = "";
+    client.host = "localhost";
+    client.database = "seabattle";
+    client.connect();
+    var sql="INSERT INTO gamelog (gameId,gamelog) VALUES ("+client.escape(process.argv[4])+","+client.escape(JSON.stringify(log))+");";
+    client.query(sql);
+    sql="UPDATE games set winner="+winnerProc+" where Id="+client.escape(process.argv[4]);
+    client.query(sql,function(){process.exit(0);});
+};
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.