summaryrefslogtreecommitdiff
path: root/botproxy.js
blob: 1f64487182653caf5bbd87d2f5faa5c450e348ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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();
});