diff options
author | tomsmeding <tom.smeding@gmail.com> | 2018-02-20 10:49:59 +0100 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2018-02-20 10:49:59 +0100 |
commit | b1b3cf82c0d0ccd6429145334c964e336858274a (patch) | |
tree | a207c7a31bf547c7c1fcd0e1823e467f606de65c /botproxy.js | |
parent | 0afba2300e370f3567de784d2e9abda22084c652 (diff) |
Botproxy
Diffstat (limited to 'botproxy.js')
-rwxr-xr-x | botproxy.js | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/botproxy.js b/botproxy.js new file mode 100755 index 0000000..1f64487 --- /dev/null +++ b/botproxy.js @@ -0,0 +1,116 @@ +#!/usr/bin/env node +const io=require("socket.io-client"); +const child_process=require("child_process"); + +let SERVER_URL=process.argv[3]?process.argv[3]:"http://localhost:15937"; +if(process.argv.length<3||process.argv.length>4){ + console.log("Usage: ./botproxy.js <./bot> [http://server-url]"); + process.exit(1); +} +const BOT_CMD=process.argv[2]; + +function boardEmpty(bd){ + for(const v of bd)if(v!=0)return false; + return true; +} + +function boardDetectMove(prev,cur){ + for(let i=0;i<prev.length;i++)if(prev[i]!=cur[i])return i; + return -1; +} + +function encodeMove(idx,size){ + return String.fromCharCode(65+idx%size)+(size-~~(idx/size)); +} + +function decodeMove(mv,size){ + return size*(size-1-(mv.charCodeAt(1)-49))+mv.charCodeAt(0)-65; +} + +function handleBotLine(line){ + console.log(`PROXY: bot<- '${line.replace("\n","")}'`); + const idx=decodeMove(line,currentGame.size); + socket.emit("game_move",currentGame.id,idx); +} + +let ME=null; +let botproc=null; +let currentGame=null; + +const socket=io(SERVER_URL); +socket.on("connect",()=>{ + socket.emit("my_info",(p)=>{ + ME=p; + console.log(`PROXY: My name: '${ME.name}'`); + }); +}); + +socket.on("err",(err)=>console.log(`ERROR: ${err}`)); + +socket.on("game_create",(game)=>{ + console.log(`PROXY: <- game_create ${JSON.stringify(game)}`); + if(game.size!=9){ + console.log("PROXY: Invited for game with non-9 size!"); + socket.emit("leave_game",game.id); + return; + } + currentGame=game; + botproc=child_process.spawn(BOT_CMD,{shell: true, stdio: ["pipe","pipe",process.stderr]}); + let botbuf=""; + botproc.stdout.on("data",(data)=>{ + botbuf+=data.toString(); + let idx=botbuf.indexOf("\n"); + while(idx!=-1){ + handleBotLine(botbuf.slice(0,idx)); + botbuf=botbuf.slice(idx+1); + idx=botbuf.indexOf("\n"); + } + }); + botproc.stdout.on("end",()=>{ + console.log("PROXY: Bot process exited!"); + botproc.kill(); + botproc=null; + if(currentGame)socket.emit("leave_game",currentGame.id); + socket.close(); + }); +}); + +socket.on("game_leave",(g,p)=>{ + console.log(`PROXY: <- game_leave ${JSON.stringify(g)} ${JSON.stringify(p)}`); + if(g.id!=currentGame.id)return; + socket.emit("leave_game",g.id); + if(botproc)botproc.kill(); + currentGame=null; +}); + +socket.on("game_turn",(g)=>{ + console.log(`PROXY: <- game_turn ${JSON.stringify(g)}`); + if(g.id!=currentGame.id)return; + if(!botproc){ + console.log("PROXY: game_turn while bot already died"); + socket.emit("leave_game",g.id); + return; + } + const prevBoard=currentGame.board; + currentGame=g; + const mv=boardDetectMove(prevBoard,currentGame.board); + const towrite=mv==-1?"Start":encodeMove(mv,currentGame.size); + botproc.stdin.write(towrite+"\n"); + console.log(`PROXY: ->bot '${towrite}'`); +}); + +socket.on("game_other_turn",(g)=>{ + console.log(`PROXY: <- game_other_turn ${JSON.stringify(g)}`); + if(g.id!=currentGame.id)return; + currentGame=g; +}); + +socket.on("game_win",(g,p)=>{ + console.log(`PROXY: <- game_win ${JSON.stringify(g)} ${JSON.stringify(p)}`); + if(g.id!=currentGame.id)return; + if(p.id==ME.id)console.log("PROXY: We won"); + else console.log("PROXY: We lost"); + socket.emit("leave_game",g.id); + if(botproc)botproc.kill(); + socket.close(); +}); |