// functions1.code




bool getElements(var f,var order,var p_elements){
	( *p_elements)={0,0,0};
	elementsN=0;
	tree=f.export();
	n=tree.getRowSize({});
	i=0;
	for(;i<n;++i){
		X=tree.getSub({i});
		if(!X.isIF());else {
			condition=X.getSub({0});
			nameX="";
			if(condition.getNames(3).size()){if(condition.typeof()=="=="){
				if(!condition.getSub({0}).getNames(3).size())nameX=eval(condition.getSub({0}));
				if(!condition.getSub({1}).getNames(3).size())nameX=eval(condition.getSub({1}));
				}}else nameX=eval(condition);
			t=order.find(nameX);
			if(t>=0){
				(*p_elements)[t]=X.getSub({1});
				++elementsN;
				}
			}
		}
	return elementsN==3;
}



var getFinalFunction(var order,var elements){
	NameCommandVar="command";
	NameID="nVrag";
	S=((set)({}));
	i=0;
	for(;i<3;++i)S.U(elements[i].getNames(3));
	S=((vector)S);
	if(S.in(NameCommandVar))NameCommandVar=S.newName(4,1);
	S.push(NameCommandVar);
	if(S.in(NameID))NameID=S.newName(4,1);
	S.push(NameID);
	resultF=PROGRAM("#;#;#;");
	i=0;
	for(;i<3;++i){
		condition=PROGRAM("if("+NameCommandVar+"==#)#;");
		condition.setSub({0,1},PROGRAM(order[i].export()));
		condition.setSub({1},elements[i]);
		resultF.setSub({i},condition);
		}
	replaceSAUsage(&resultF,NameID);
	resultF=resultF.toFunction();
	resultF.setName("protokol");
	resultF.setNamesStart({NameCommandVar,NameID,"obj"});
	return resultF;
}



var ReplaceVarsToObjXinTree(var plaw,var NameObjX,var free){
	if(!isset(free))free={};
	access={};
	fs={};
	stoper=0;
	do{
		n=plaw->getRowSize(access);
		if(access.empty()){
			sub=plaw->getSub(access);
			if(typeof(sub.typeof())!="void"){if(sub.typeof()=="function")fs.push(access+{0});}
			}
		access.push(n);
		ok=1;
		while(access.size()&&ok){
			n=access.pop();
			--n;
			if(n<0||stoper){
				stoper=0;
				continue;
				}
			access.push(n);
			if(fs.size()){if(access==fs.end()){
				fs.pop();
				continue;
				}}
			sub=plaw->getSub(access);
			if(typeof(sub.typeof())!="void"){
				if(sub.typeof()=="function")fs.push(access+{0});
				if(sub.typeof()=="var"){if(!free.in(((string)sub))){
					W=PROGRAM(NameObjX+"->#");
					W.setSub({1},sub);
					plaw->setSub(access,W);
					stoper=1;
					}}
				}
			ok=0;
			}
		}while(access.size());
}



void replaceSAUsage(var plaw,var NameID){
	access={};
	do{
		n=plaw->getRowSize(access);
		if(access.empty()){
			sub=plaw->getSub(access);
			if(typeof(sub.typeof())!="void"){if(sub.typeof()=="function"){
				if(((string)sub.getSub({0}))=="Send"){
					X=PROGRAM("Send("+NameID+",#,1)");
					X.setSub({2},sub.getSub({1}));
					plaw->setSub(access,X);
					}
				if(((string)sub.getSub({0}))=="Accept"){
					X=PROGRAM("Accept("+NameID+",1)");
					plaw->setSub(access,X);
					}
				}}
			}
		access.push(n);
		ok=1;
		while(access.size()&&ok){
			n=access.pop();
			--n;
			if(n<0)continue;
			access.push(n);
			sub=plaw->getSub(access);
			if(typeof(sub.typeof())!="void"){if(sub.typeof()=="function"){
				if(((string)sub.getSub({0}))=="Send"){
					X=PROGRAM("Send("+NameID+",#,1)");
					X.setSub({2},sub.getSub({1}));
					plaw->setSub(access,X);
					}
				if(((string)sub.getSub({0}))=="Accept"){
					X=PROGRAM("Accept("+NameID+",1)");
					plaw->setSub(access,X);
					}
				}}
			ok=0;
			}
		}while(access.size());
}



var platforma(var resultF,var resultF2,var n){
	Result={{0,0},{0,0}};
	i=0;
	for(;i<n;++i){
		R=ServerW2(resultF,resultF2);
		Result[0][0]+=R[0][0];
		Result[0][1]+=R[0][1];
		Result[1][0]+=R[1][0];
		Result[1][1]+=R[1][1];
		}
	return Result;
}



var ServerW2(var resultF,var resultF2){
	fork("ClientW1",getThisLaverNumber(),0);
	fork("ClientW1",getThisLaverNumber(),1);
	BotsNumberLaver={# ,# };
	Winner={0,0};
	Q=Accept();
	BotsNumberLaver[Q[1]]=Q[0];
	Q=Accept();
	BotsNumberLaver[Q[1]]=Q[0];
	Send(BotsNumberLaver[0],BotsNumberLaver[1],1);
	Send(BotsNumberLaver[1],BotsNumberLaver[0],1);
	Send(BotsNumberLaver[0],resultF,1);
	Send(BotsNumberLaver[1],resultF2,1);
	nxod=# %2;
	Send(BotsNumberLaver[0],!nxod,1);
	Send(BotsNumberLaver[1],nxod,1);
	do{
		Q=Accept();
		ok=Q[1];
		id=Q[0]==BotsNumberLaver[0]?1:0;
		ok2=Accept(BotsNumberLaver[id]);
		ok3=ok&&ok2;
		if(ok2)Send(BotsNumberLaver[id],ok3,1);
		if(ok)Send(Q[0],ok3,1);
		}while(ok3);
	Winner[id]=ok;
	Winner[1-id]=ok2;
	R={Winner};
	R.push({Winner[nxod],Winner[!nxod]});
	return R;
}



void ClientW1(var nServer,var meNumber){
	Send(nServer,meNumber,1);
	nProtivnic=Accept(nServer);
	law=Accept(nServer);
	meXod=Accept(nServer);
	obj=((map)({}));
	law.run("подготовка",nProtivnic,&obj);
	while(1){
		ok=0;
		if(ControlOFF()){
			law.run(meXod?"атака":"ответ",nProtivnic,&obj);
			ok=1;
			}
		ClearPsetOFF();
		Send(nServer,ok,1);
		if(!ok)break;
		ok=Accept(nServer);
		if(!ok)break;
		meXod= !meXod;
		}
}


// functions1.code	:-|